Whamcloud - gitweb
LU-12495 obdclass: qos penalties miscalculated
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
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-11667 LU-4398
57         ALWAYS_EXCEPT+=" 45       317      817"
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:
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
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 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1746 # if the OST isn't full anymore.
1747 reset_enospc() {
1748         local OSTIDX=${1:-""}
1749
1750         local list=$(comma_list $(osts_nodes))
1751         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1752
1753         do_nodes $list lctl set_param fail_loc=0
1754         sync    # initiate all OST_DESTROYs from MDS to OST
1755         sleep_maxage
1756 }
1757
1758 exhaust_precreations() {
1759         local OSTIDX=$1
1760         local FAILLOC=$2
1761         local FAILIDX=${3:-$OSTIDX}
1762         local ofacet=ost$((OSTIDX + 1))
1763
1764         test_mkdir -p -c1 $DIR/$tdir
1765         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1766         local mfacet=mds$((mdtidx + 1))
1767         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1768
1769         local OST=$(ostname_from_index $OSTIDX)
1770
1771         # on the mdt's osc
1772         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1773         local last_id=$(do_facet $mfacet lctl get_param -n \
1774                         osp.$mdtosc_proc1.prealloc_last_id)
1775         local next_id=$(do_facet $mfacet lctl get_param -n \
1776                         osp.$mdtosc_proc1.prealloc_next_id)
1777
1778         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1779         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1780
1781         test_mkdir -p $DIR/$tdir/${OST}
1782         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1783 #define OBD_FAIL_OST_ENOSPC              0x215
1784         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1785         echo "Creating to objid $last_id on ost $OST..."
1786         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1787         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1788         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1789         sleep_maxage
1790 }
1791
1792 exhaust_all_precreations() {
1793         local i
1794         for (( i=0; i < OSTCOUNT; i++ )) ; do
1795                 exhaust_precreations $i $1 -1
1796         done
1797 }
1798
1799 test_27n() {
1800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1802         remote_mds_nodsh && skip "remote MDS with nodsh"
1803         remote_ost_nodsh && skip "remote OST with nodsh"
1804
1805         reset_enospc
1806         rm -f $DIR/$tdir/$tfile
1807         exhaust_precreations 0 0x80000215
1808         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1809         touch $DIR/$tdir/$tfile || error "touch failed"
1810         $LFS getstripe $DIR/$tdir/$tfile
1811         reset_enospc
1812 }
1813 run_test 27n "create file with some full OSTs"
1814
1815 test_27o() {
1816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1818         remote_mds_nodsh && skip "remote MDS with nodsh"
1819         remote_ost_nodsh && skip "remote OST with nodsh"
1820
1821         reset_enospc
1822         rm -f $DIR/$tdir/$tfile
1823         exhaust_all_precreations 0x215
1824
1825         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1826
1827         reset_enospc
1828         rm -rf $DIR/$tdir/*
1829 }
1830 run_test 27o "create file with all full OSTs (should error)"
1831
1832 test_27p() {
1833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836         remote_ost_nodsh && skip "remote OST with nodsh"
1837
1838         reset_enospc
1839         rm -f $DIR/$tdir/$tfile
1840         test_mkdir $DIR/$tdir
1841
1842         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1843         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1844         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1845
1846         exhaust_precreations 0 0x80000215
1847         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1848         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1849         $LFS getstripe $DIR/$tdir/$tfile
1850
1851         reset_enospc
1852 }
1853 run_test 27p "append to a truncated file with some full OSTs"
1854
1855 test_27q() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863
1864         test_mkdir $DIR/$tdir
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1867                 error "truncate $DIR/$tdir/$tfile failed"
1868         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1869
1870         exhaust_all_precreations 0x215
1871
1872         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1873         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1874
1875         reset_enospc
1876 }
1877 run_test 27q "append to truncated file with all OSTs full (should error)"
1878
1879 test_27r() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_precreations 0 0x80000215
1888
1889         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1890
1891         reset_enospc
1892 }
1893 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1894
1895 test_27s() { # bug 10725
1896         test_mkdir $DIR/$tdir
1897         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1898         local stripe_count=0
1899         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1900         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1901                 error "stripe width >= 2^32 succeeded" || true
1902
1903 }
1904 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1905
1906 test_27t() { # bug 10864
1907         WDIR=$(pwd)
1908         WLFS=$(which lfs)
1909         cd $DIR
1910         touch $tfile
1911         $WLFS getstripe $tfile
1912         cd $WDIR
1913 }
1914 run_test 27t "check that utils parse path correctly"
1915
1916 test_27u() { # bug 4900
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919
1920         local index
1921         local list=$(comma_list $(mdts_nodes))
1922
1923 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1924         do_nodes $list $LCTL set_param fail_loc=0x139
1925         test_mkdir -p $DIR/$tdir
1926         trap simple_cleanup_common EXIT
1927         createmany -o $DIR/$tdir/t- 1000
1928         do_nodes $list $LCTL set_param fail_loc=0
1929
1930         TLOG=$TMP/$tfile.getstripe
1931         $LFS getstripe $DIR/$tdir > $TLOG
1932         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1933         unlinkmany $DIR/$tdir/t- 1000
1934         trap 0
1935         [[ $OBJS -gt 0 ]] &&
1936                 error "$OBJS objects created on OST-0. See $TLOG" ||
1937                 rm -f $TLOG
1938 }
1939 run_test 27u "skip object creation on OSC w/o objects"
1940
1941 test_27v() { # bug 4900
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         exhaust_all_precreations 0x215
1948         reset_enospc
1949
1950         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1951
1952         touch $DIR/$tdir/$tfile
1953         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1954         # all except ost1
1955         for (( i=1; i < OSTCOUNT; i++ )); do
1956                 do_facet ost$i lctl set_param fail_loc=0x705
1957         done
1958         local START=`date +%s`
1959         createmany -o $DIR/$tdir/$tfile 32
1960
1961         local FINISH=`date +%s`
1962         local TIMEOUT=`lctl get_param -n timeout`
1963         local PROCESS=$((FINISH - START))
1964         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1965                error "$FINISH - $START >= $TIMEOUT / 2"
1966         sleep $((TIMEOUT / 2 - PROCESS))
1967         reset_enospc
1968 }
1969 run_test 27v "skip object creation on slow OST"
1970
1971 test_27w() { # bug 10997
1972         test_mkdir $DIR/$tdir
1973         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1974         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1975                 error "stripe size $size != 65536" || true
1976         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1977                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1978 }
1979 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1980
1981 test_27wa() {
1982         [[ $OSTCOUNT -lt 2 ]] &&
1983                 skip_env "skipping multiple stripe count/offset test"
1984
1985         test_mkdir $DIR/$tdir
1986         for i in $(seq 1 $OSTCOUNT); do
1987                 offset=$((i - 1))
1988                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1989                         error "setstripe -c $i -i $offset failed"
1990                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1991                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1992                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1993                 [ $index -ne $offset ] &&
1994                         error "stripe offset $index != $offset" || true
1995         done
1996 }
1997 run_test 27wa "check $LFS setstripe -c -i options"
1998
1999 test_27x() {
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003
2004         OFFSET=$(($OSTCOUNT - 1))
2005         OSTIDX=0
2006         local OST=$(ostname_from_index $OSTIDX)
2007
2008         test_mkdir $DIR/$tdir
2009         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2010         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2011         sleep_maxage
2012         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2013         for i in $(seq 0 $OFFSET); do
2014                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2015                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2016                 error "OST0 was degraded but new created file still use it"
2017         done
2018         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2019 }
2020 run_test 27x "create files while OST0 is degraded"
2021
2022 test_27y() {
2023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2024         remote_mds_nodsh && skip "remote MDS with nodsh"
2025         remote_ost_nodsh && skip "remote OST with nodsh"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027
2028         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2029         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2030                 osp.$mdtosc.prealloc_last_id)
2031         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2032                 osp.$mdtosc.prealloc_next_id)
2033         local fcount=$((last_id - next_id))
2034         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2035         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2036
2037         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2038                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2039         local OST_DEACTIVE_IDX=-1
2040         local OSC
2041         local OSTIDX
2042         local OST
2043
2044         for OSC in $MDS_OSCS; do
2045                 OST=$(osc_to_ost $OSC)
2046                 OSTIDX=$(index_from_ostuuid $OST)
2047                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2048                         OST_DEACTIVE_IDX=$OSTIDX
2049                 fi
2050                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2051                         echo $OSC "is Deactivated:"
2052                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2053                 fi
2054         done
2055
2056         OSTIDX=$(index_from_ostuuid $OST)
2057         test_mkdir $DIR/$tdir
2058         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2059
2060         for OSC in $MDS_OSCS; do
2061                 OST=$(osc_to_ost $OSC)
2062                 OSTIDX=$(index_from_ostuuid $OST)
2063                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2064                         echo $OST "is degraded:"
2065                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2066                                                 obdfilter.$OST.degraded=1
2067                 fi
2068         done
2069
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $fcount
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is recovered from degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=0
2080                 else
2081                         do_facet $SINGLEMDS lctl --device %$OSC activate
2082                 fi
2083         done
2084
2085         # all osp devices get activated, hence -1 stripe count restored
2086         local stripe_count=0
2087
2088         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2089         # devices get activated.
2090         sleep_maxage
2091         $LFS setstripe -c -1 $DIR/$tfile
2092         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2093         rm -f $DIR/$tfile
2094         [ $stripe_count -ne $OSTCOUNT ] &&
2095                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2096         return 0
2097 }
2098 run_test 27y "create files while OST0 is degraded and the rest inactive"
2099
2100 check_seq_oid()
2101 {
2102         log "check file $1"
2103
2104         lmm_count=$($LFS getstripe -c $1)
2105         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2106         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2107
2108         local old_ifs="$IFS"
2109         IFS=$'[:]'
2110         fid=($($LFS path2fid $1))
2111         IFS="$old_ifs"
2112
2113         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2114         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2115
2116         # compare lmm_seq and lu_fid->f_seq
2117         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2118         # compare lmm_object_id and lu_fid->oid
2119         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2120
2121         # check the trusted.fid attribute of the OST objects of the file
2122         local have_obdidx=false
2123         local stripe_nr=0
2124         $LFS getstripe $1 | while read obdidx oid hex seq; do
2125                 # skip lines up to and including "obdidx"
2126                 [ -z "$obdidx" ] && break
2127                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2128                 $have_obdidx || continue
2129
2130                 local ost=$((obdidx + 1))
2131                 local dev=$(ostdevname $ost)
2132                 local oid_hex
2133
2134                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2135
2136                 seq=$(echo $seq | sed -e "s/^0x//g")
2137                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2138                         oid_hex=$(echo $oid)
2139                 else
2140                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2141                 fi
2142                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2143
2144                 local ff=""
2145                 #
2146                 # Don't unmount/remount the OSTs if we don't need to do that.
2147                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2148                 # update too, until that use mount/ll_decode_filter_fid/mount.
2149                 # Re-enable when debugfs will understand new filter_fid.
2150                 #
2151                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2152                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2153                                 $dev 2>/dev/null" | grep "parent=")
2154                 fi
2155                 if [ -z "$ff" ]; then
2156                         stop ost$ost
2157                         mount_fstype ost$ost
2158                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2159                                 $(facet_mntpt ost$ost)/$obj_file)
2160                         unmount_fstype ost$ost
2161                         start ost$ost $dev $OST_MOUNT_OPTS
2162                         clients_up
2163                 fi
2164
2165                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2166
2167                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2168
2169                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2170                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2171                 #
2172                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2173                 #       stripe_size=1048576 component_id=1 component_start=0 \
2174                 #       component_end=33554432
2175                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2176                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2177                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2178                 local ff_pstripe
2179                 if grep -q 'stripe=' <<<$ff; then
2180                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2181                 else
2182                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2183                         # into f_ver in this case.  See comment on ff_parent.
2184                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2185                 fi
2186
2187                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2188                 [ $ff_pseq = $lmm_seq ] ||
2189                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2190                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2191                 [ $ff_poid = $lmm_oid ] ||
2192                         error "FF parent OID $ff_poid != $lmm_oid"
2193                 (($ff_pstripe == $stripe_nr)) ||
2194                         error "FF stripe $ff_pstripe != $stripe_nr"
2195
2196                 stripe_nr=$((stripe_nr + 1))
2197                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2198                         continue
2199                 if grep -q 'stripe_count=' <<<$ff; then
2200                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2201                                             -e 's/ .*//' <<<$ff)
2202                         [ $lmm_count = $ff_scnt ] ||
2203                                 error "FF stripe count $lmm_count != $ff_scnt"
2204                 fi
2205         done
2206 }
2207
2208 test_27z() {
2209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2210         remote_ost_nodsh && skip "remote OST with nodsh"
2211
2212         test_mkdir $DIR/$tdir
2213         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2214                 { error "setstripe -c -1 failed"; return 1; }
2215         # We need to send a write to every object to get parent FID info set.
2216         # This _should_ also work for setattr, but does not currently.
2217         # touch $DIR/$tdir/$tfile-1 ||
2218         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2219                 { error "dd $tfile-1 failed"; return 2; }
2220         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2221                 { error "setstripe -c -1 failed"; return 3; }
2222         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2223                 { error "dd $tfile-2 failed"; return 4; }
2224
2225         # make sure write RPCs have been sent to OSTs
2226         sync; sleep 5; sync
2227
2228         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2229         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2230 }
2231 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2232
2233 test_27A() { # b=19102
2234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2235
2236         save_layout_restore_at_exit $MOUNT
2237         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2238         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2239                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2240         local default_size=$($LFS getstripe -S $MOUNT)
2241         local default_offset=$($LFS getstripe -i $MOUNT)
2242         local dsize=$(do_facet $SINGLEMDS \
2243                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2244         [ $default_size -eq $dsize ] ||
2245                 error "stripe size $default_size != $dsize"
2246         [ $default_offset -eq -1 ] ||
2247                 error "stripe offset $default_offset != -1"
2248 }
2249 run_test 27A "check filesystem-wide default LOV EA values"
2250
2251 test_27B() { # LU-2523
2252         test_mkdir $DIR/$tdir
2253         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2254         touch $DIR/$tdir/f0
2255         # open f1 with O_LOV_DELAY_CREATE
2256         # rename f0 onto f1
2257         # call setstripe ioctl on open file descriptor for f1
2258         # close
2259         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2260                 $DIR/$tdir/f0
2261
2262         rm -f $DIR/$tdir/f1
2263         # open f1 with O_LOV_DELAY_CREATE
2264         # unlink f1
2265         # call setstripe ioctl on open file descriptor for f1
2266         # close
2267         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2268
2269         # Allow multiop to fail in imitation of NFS's busted semantics.
2270         true
2271 }
2272 run_test 27B "call setstripe on open unlinked file/rename victim"
2273
2274 # 27C family tests full striping and overstriping
2275 test_27Ca() { #LU-2871
2276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2277
2278         declare -a ost_idx
2279         local index
2280         local found
2281         local i
2282         local j
2283
2284         test_mkdir $DIR/$tdir
2285         cd $DIR/$tdir
2286         for i in $(seq 0 $((OSTCOUNT - 1))); do
2287                 # set stripe across all OSTs starting from OST$i
2288                 $LFS setstripe -i $i -c -1 $tfile$i
2289                 # get striping information
2290                 ost_idx=($($LFS getstripe $tfile$i |
2291                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2292                 echo ${ost_idx[@]}
2293
2294                 # check the layout
2295                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2296                         error "${#ost_idx[@]} != $OSTCOUNT"
2297
2298                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2299                         found=0
2300                         for j in $(echo ${ost_idx[@]}); do
2301                                 if [ $index -eq $j ]; then
2302                                         found=1
2303                                         break
2304                                 fi
2305                         done
2306                         [ $found = 1 ] ||
2307                                 error "Can not find $index in ${ost_idx[@]}"
2308                 done
2309         done
2310 }
2311 run_test 27Ca "check full striping across all OSTs"
2312
2313 test_27Cb() {
2314         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2315                 skip "server does not support overstriping"
2316         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2317                 skip_env "too many osts, skipping"
2318
2319         test_mkdir -p $DIR/$tdir
2320         local setcount=$(($OSTCOUNT * 2))
2321         [ $setcount -ge 160 ] || large_xattr_enabled ||
2322                 skip_env "ea_inode feature disabled"
2323
2324         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2325                 error "setstripe failed"
2326
2327         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2328         [ $count -eq $setcount ] ||
2329                 error "stripe count $count, should be $setcount"
2330
2331         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2332                 error "overstriped should be set in pattern"
2333
2334         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2335                 error "dd failed"
2336 }
2337 run_test 27Cb "more stripes than OSTs with -C"
2338
2339 test_27Cc() {
2340         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2341                 skip "server does not support overstriping"
2342         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2343
2344         test_mkdir -p $DIR/$tdir
2345         local setcount=$(($OSTCOUNT - 1))
2346
2347         [ $setcount -ge 160 ] || large_xattr_enabled ||
2348                 skip_env "ea_inode feature disabled"
2349
2350         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2351                 error "setstripe failed"
2352
2353         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2354         [ $count -eq $setcount ] ||
2355                 error "stripe count $count, should be $setcount"
2356
2357         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2358                 error "overstriped should not be set in pattern"
2359
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2361                 error "dd failed"
2362 }
2363 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2364
2365 test_27Cd() {
2366         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2367                 skip "server does not support overstriping"
2368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2369         large_xattr_enabled || skip_env "ea_inode feature disabled"
2370
2371         test_mkdir -p $DIR/$tdir
2372         local setcount=$LOV_MAX_STRIPE_COUNT
2373
2374         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2375                 error "setstripe failed"
2376
2377         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2378         [ $count -eq $setcount ] ||
2379                 error "stripe count $count, should be $setcount"
2380
2381         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2382                 error "overstriped should be set in pattern"
2383
2384         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2385                 error "dd failed"
2386
2387         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2388 }
2389 run_test 27Cd "test maximum stripe count"
2390
2391 test_27Ce() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         test_mkdir -p $DIR/$tdir
2395
2396         pool_add $TESTNAME || error "Pool creation failed"
2397         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2398
2399         local setcount=8
2400
2401         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2402                 error "setstripe failed"
2403
2404         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2405         [ $count -eq $setcount ] ||
2406                 error "stripe count $count, should be $setcount"
2407
2408         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2409                 error "overstriped should be set in pattern"
2410
2411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2412                 error "dd failed"
2413
2414         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2415 }
2416 run_test 27Ce "test pool with overstriping"
2417
2418 test_27Cf() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2422                 skip_env "too many osts, skipping"
2423
2424         test_mkdir -p $DIR/$tdir
2425
2426         local setcount=$(($OSTCOUNT * 2))
2427         [ $setcount -ge 160 ] || large_xattr_enabled ||
2428                 skip_env "ea_inode feature disabled"
2429
2430         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2431                 error "setstripe failed"
2432
2433         echo 1 > $DIR/$tdir/$tfile
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444
2445         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2446 }
2447 run_test 27Cf "test default inheritance with overstriping"
2448
2449 test_27D() {
2450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2452         remote_mds_nodsh && skip "remote MDS with nodsh"
2453
2454         local POOL=${POOL:-testpool}
2455         local first_ost=0
2456         local last_ost=$(($OSTCOUNT - 1))
2457         local ost_step=1
2458         local ost_list=$(seq $first_ost $ost_step $last_ost)
2459         local ost_range="$first_ost $last_ost $ost_step"
2460
2461         test_mkdir $DIR/$tdir
2462         pool_add $POOL || error "pool_add failed"
2463         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2464
2465         local skip27D
2466         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2467                 skip27D+="-s 29"
2468         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2469                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2470                         skip27D+=" -s 30,31"
2471         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2472                 skip27D+="-s 32"
2473         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2474           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2475                 skip27D+=" -s 32,33"
2476         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2477                 error "llapi_layout_test failed"
2478
2479         destroy_test_pools || error "destroy test pools failed"
2480 }
2481 run_test 27D "validate llapi_layout API"
2482
2483 # Verify that default_easize is increased from its initial value after
2484 # accessing a widely striped file.
2485 test_27E() {
2486         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2487         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2488                 skip "client does not have LU-3338 fix"
2489
2490         # 72 bytes is the minimum space required to store striping
2491         # information for a file striped across one OST:
2492         # (sizeof(struct lov_user_md_v3) +
2493         #  sizeof(struct lov_user_ost_data_v1))
2494         local min_easize=72
2495         $LCTL set_param -n llite.*.default_easize $min_easize ||
2496                 error "lctl set_param failed"
2497         local easize=$($LCTL get_param -n llite.*.default_easize)
2498
2499         [ $easize -eq $min_easize ] ||
2500                 error "failed to set default_easize"
2501
2502         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2503                 error "setstripe failed"
2504         # In order to ensure stat() call actually talks to MDS we need to
2505         # do something drastic to this file to shake off all lock, e.g.
2506         # rename it (kills lookup lock forcing cache cleaning)
2507         mv $DIR/$tfile $DIR/${tfile}-1
2508         ls -l $DIR/${tfile}-1
2509         rm $DIR/${tfile}-1
2510
2511         easize=$($LCTL get_param -n llite.*.default_easize)
2512
2513         [ $easize -gt $min_easize ] ||
2514                 error "default_easize not updated"
2515 }
2516 run_test 27E "check that default extended attribute size properly increases"
2517
2518 test_27F() { # LU-5346/LU-7975
2519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2520         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2521         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2522                 skip "Need MDS version at least 2.8.51"
2523         remote_ost_nodsh && skip "remote OST with nodsh"
2524
2525         test_mkdir $DIR/$tdir
2526         rm -f $DIR/$tdir/f0
2527         $LFS setstripe -c 2 $DIR/$tdir
2528
2529         # stop all OSTs to reproduce situation for LU-7975 ticket
2530         for num in $(seq $OSTCOUNT); do
2531                 stop ost$num
2532         done
2533
2534         # open/create f0 with O_LOV_DELAY_CREATE
2535         # truncate f0 to a non-0 size
2536         # close
2537         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2538
2539         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2540         # open/write it again to force delayed layout creation
2541         cat /etc/hosts > $DIR/$tdir/f0 &
2542         catpid=$!
2543
2544         # restart OSTs
2545         for num in $(seq $OSTCOUNT); do
2546                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2547                         error "ost$num failed to start"
2548         done
2549
2550         wait $catpid || error "cat failed"
2551
2552         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2553         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2554                 error "wrong stripecount"
2555
2556 }
2557 run_test 27F "Client resend delayed layout creation with non-zero size"
2558
2559 test_27G() { #LU-10629
2560         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2561                 skip "Need MDS version at least 2.11.51"
2562         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2563         remote_mds_nodsh && skip "remote MDS with nodsh"
2564         local POOL=${POOL:-testpool}
2565         local ostrange="0 0 1"
2566
2567         test_mkdir $DIR/$tdir
2568         pool_add $POOL || error "pool_add failed"
2569         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2570         $LFS setstripe -p $POOL $DIR/$tdir
2571
2572         local pool=$($LFS getstripe -p $DIR/$tdir)
2573
2574         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2575
2576         $LFS setstripe -d $DIR/$tdir
2577
2578         pool=$($LFS getstripe -p $DIR/$tdir)
2579
2580         rmdir $DIR/$tdir
2581
2582         [ -z "$pool" ] || error "'$pool' is not empty"
2583 }
2584 run_test 27G "Clear OST pool from stripe"
2585
2586 test_27H() {
2587         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2588                 skip "Need MDS version newer than 2.11.54"
2589         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2590         test_mkdir $DIR/$tdir
2591         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2592         touch $DIR/$tdir/$tfile
2593         $LFS getstripe -c $DIR/$tdir/$tfile
2594         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2595                 error "two-stripe file doesn't have two stripes"
2596
2597         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2598         $LFS getstripe -y $DIR/$tdir/$tfile
2599         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2600              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2601                 error "expected l_ost_idx: [02]$ not matched"
2602
2603         # make sure ost list has been cleared
2604         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2605         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2606                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2607         touch $DIR/$tdir/f3
2608         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2609 }
2610 run_test 27H "Set specific OSTs stripe"
2611
2612 test_27I() {
2613         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2614         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2615         local pool=$TESTNAME
2616         local ostrange="1 1 1"
2617
2618         save_layout_restore_at_exit $MOUNT
2619         $LFS setstripe -c 2 -i 0 $MOUNT
2620         pool_add $pool || error "pool_add failed"
2621         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2622         test_mkdir $DIR/$tdir
2623         $LFS setstripe -p $pool $DIR/$tdir
2624         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2625         $LFS getstripe $DIR/$tdir/$tfile
2626 }
2627 run_test 27I "check that root dir striping does not break parent dir one"
2628
2629 test_27J() {
2630         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2631                 skip "Need MDS version newer than 2.12.51"
2632
2633         test_mkdir $DIR/$tdir
2634         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2635         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2636
2637         # create foreign file (raw way)
2638         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2639                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2640
2641         # verify foreign file (raw way)
2642         parse_foreign_file -f $DIR/$tdir/$tfile |
2643                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2644                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2645         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2646                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2647         parse_foreign_file -f $DIR/$tdir/$tfile |
2648                 grep "lov_foreign_size: 73" ||
2649                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_type: 1" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2653         parse_foreign_file -f $DIR/$tdir/$tfile |
2654                 grep "lov_foreign_flags: 0x0000DA08" ||
2655                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2656         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2657                 grep "lov_foreign_value: 0x" |
2658                 sed -e 's/lov_foreign_value: 0x//')
2659         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2660         [[ $lov = ${lov2// /} ]] ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2662
2663         # create foreign file (lfs + API)
2664         $LFS setstripe --foreign=daos --flags 0xda08 \
2665                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2666                 error "$DIR/$tdir/${tfile}2: create failed"
2667
2668         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2669                 grep "lfm_magic:.*0x0BD70BD0" ||
2670                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2671         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2672         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2673                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2674         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2675                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_flags:.*0x0000DA08" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2679         $LFS getstripe $DIR/$tdir/${tfile}2 |
2680                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2682
2683         # modify striping should fail
2684         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2685                 error "$DIR/$tdir/$tfile: setstripe should fail"
2686         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2687                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2688
2689         # R/W should fail
2690         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2691         cat $DIR/$tdir/${tfile}2 &&
2692                 error "$DIR/$tdir/${tfile}2: read should fail"
2693         cat /etc/passwd > $DIR/$tdir/$tfile &&
2694                 error "$DIR/$tdir/$tfile: write should fail"
2695         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2696                 error "$DIR/$tdir/${tfile}2: write should fail"
2697
2698         # chmod should work
2699         chmod 222 $DIR/$tdir/$tfile ||
2700                 error "$DIR/$tdir/$tfile: chmod failed"
2701         chmod 222 $DIR/$tdir/${tfile}2 ||
2702                 error "$DIR/$tdir/${tfile}2: chmod failed"
2703
2704         # chown should work
2705         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2706                 error "$DIR/$tdir/$tfile: chown failed"
2707         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2708                 error "$DIR/$tdir/${tfile}2: chown failed"
2709
2710         # rename should work
2711         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2712                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2713         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2714                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2715
2716         #remove foreign file
2717         rm $DIR/$tdir/${tfile}.new ||
2718                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2719         rm $DIR/$tdir/${tfile}2.new ||
2720                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2721 }
2722 run_test 27J "basic ops on file with foreign LOV"
2723
2724 test_27K() {
2725         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2726                 skip "Need MDS version newer than 2.12.49"
2727
2728         test_mkdir $DIR/$tdir
2729         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2730         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2731
2732         # create foreign dir (raw way)
2733         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2734                 error "create_foreign_dir FAILED"
2735
2736         # verify foreign dir (raw way)
2737         parse_foreign_dir -d $DIR/$tdir/$tdir |
2738                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2739                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2740         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2741                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2742         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2743                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2744         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2745                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2746         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2747                 grep "lmv_foreign_value: 0x" |
2748                 sed 's/lmv_foreign_value: 0x//')
2749         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2750                 sed 's/ //g')
2751         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2752
2753         # create foreign dir (lfs + API)
2754         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2755                 $DIR/$tdir/${tdir}2 ||
2756                 error "$DIR/$tdir/${tdir}2: create failed"
2757
2758         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2759                 grep "lfm_magic:.*0x0CD50CD0" ||
2760                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2761         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2762         # - sizeof(lfm_type) - sizeof(lfm_flags)
2763         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2764                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2765         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2766                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2767         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2768                 grep "lfm_flags:.*0x0000DA05" ||
2769                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2770         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2771                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2773
2774         # file create in dir should fail
2775         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2776         touch $DIR/$tdir/${tdir}2/$tfile &&
2777                 "$DIR/${tdir}2: file create should fail"
2778
2779         # chmod should work
2780         chmod 777 $DIR/$tdir/$tdir ||
2781                 error "$DIR/$tdir: chmod failed"
2782         chmod 777 $DIR/$tdir/${tdir}2 ||
2783                 error "$DIR/${tdir}2: chmod failed"
2784
2785         # chown should work
2786         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2787                 error "$DIR/$tdir: chown failed"
2788         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2789                 error "$DIR/${tdir}2: chown failed"
2790
2791         # rename should work
2792         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2793                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2794         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2795                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2796
2797         #remove foreign dir
2798         rmdir $DIR/$tdir/${tdir}.new ||
2799                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2800         rmdir $DIR/$tdir/${tdir}2.new ||
2801                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2802 }
2803 run_test 27K "basic ops on dir with foreign LMV"
2804
2805 test_27L() {
2806         remote_mds_nodsh && skip "remote MDS with nodsh"
2807
2808         local POOL=${POOL:-$TESTNAME}
2809
2810         pool_add $POOL || error "pool_add failed"
2811
2812         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2813                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2814                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2815 }
2816 run_test 27L "lfs pool_list gives correct pool name"
2817
2818 test_27M() {
2819         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2820                 skip "Need MDS version >= than 2.12.57"
2821         remote_mds_nodsh && skip "remote MDS with nodsh"
2822         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2823
2824         test_mkdir $DIR/$tdir
2825
2826         # Set default striping on directory
2827         $LFS setstripe -C 4 $DIR/$tdir
2828
2829         echo 1 > $DIR/$tdir/${tfile}.1
2830         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2831         local setcount=4
2832         [ $count -eq $setcount ] ||
2833                 error "(1) stripe count $count, should be $setcount"
2834
2835         # Capture existing append_stripe_count setting for restore
2836         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2837         local mdts=$(comma_list $(mdts_nodes))
2838         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2839
2840         local appendcount=$orig_count
2841         echo 1 >> $DIR/$tdir/${tfile}.2_append
2842         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2843         [ $count -eq $appendcount ] ||
2844                 error "(2)stripe count $count, should be $appendcount for append"
2845
2846         # Disable O_APPEND striping, verify it works
2847         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2848
2849         # Should now get the default striping, which is 4
2850         setcount=4
2851         echo 1 >> $DIR/$tdir/${tfile}.3_append
2852         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2853         [ $count -eq $setcount ] ||
2854                 error "(3) stripe count $count, should be $setcount"
2855
2856         # Try changing the stripe count for append files
2857         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2858
2859         # Append striping is now 2 (directory default is still 4)
2860         appendcount=2
2861         echo 1 >> $DIR/$tdir/${tfile}.4_append
2862         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2863         [ $count -eq $appendcount ] ||
2864                 error "(4) stripe count $count, should be $appendcount for append"
2865
2866         # Test append stripe count of -1
2867         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2868         appendcount=$OSTCOUNT
2869         echo 1 >> $DIR/$tdir/${tfile}.5
2870         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2871         [ $count -eq $appendcount ] ||
2872                 error "(5) stripe count $count, should be $appendcount for append"
2873
2874         # Set append striping back to default of 1
2875         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2876
2877         # Try a new default striping, PFL + DOM
2878         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2879
2880         # Create normal DOM file, DOM returns stripe count == 0
2881         setcount=0
2882         touch $DIR/$tdir/${tfile}.6
2883         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2884         [ $count -eq $setcount ] ||
2885                 error "(6) stripe count $count, should be $setcount"
2886
2887         # Show
2888         appendcount=1
2889         echo 1 >> $DIR/$tdir/${tfile}.7_append
2890         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2891         [ $count -eq $appendcount ] ||
2892                 error "(7) stripe count $count, should be $appendcount for append"
2893
2894         # Clean up DOM layout
2895         $LFS setstripe -d $DIR/$tdir
2896
2897         # Now test that append striping works when layout is from root
2898         $LFS setstripe -c 2 $MOUNT
2899         # Make a special directory for this
2900         mkdir $DIR/${tdir}/${tdir}.2
2901         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2902
2903         # Verify for normal file
2904         setcount=2
2905         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2906         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2907         [ $count -eq $setcount ] ||
2908                 error "(8) stripe count $count, should be $setcount"
2909
2910         appendcount=1
2911         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2912         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2913         [ $count -eq $appendcount ] ||
2914                 error "(9) stripe count $count, should be $appendcount for append"
2915
2916         # Now test O_APPEND striping with pools
2917         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2918         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2919
2920         # Create the pool
2921         pool_add $TESTNAME || error "pool creation failed"
2922         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2923
2924         echo 1 >> $DIR/$tdir/${tfile}.10_append
2925
2926         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2927         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2928
2929         # Check that count is still correct
2930         appendcount=1
2931         echo 1 >> $DIR/$tdir/${tfile}.11_append
2932         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2933         [ $count -eq $appendcount ] ||
2934                 error "(11) stripe count $count, should be $appendcount for append"
2935
2936         # Disable O_APPEND stripe count, verify pool works separately
2937         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2938
2939         echo 1 >> $DIR/$tdir/${tfile}.12_append
2940
2941         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2942         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2943
2944         # Remove pool setting, verify it's not applied
2945         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2946
2947         echo 1 >> $DIR/$tdir/${tfile}.13_append
2948
2949         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2950         [ "$pool" = "" ] || error "(13) pool found: $pool"
2951 }
2952 run_test 27M "test O_APPEND striping"
2953
2954 test_27N() {
2955         combined_mgs_mds && skip "needs separate MGS/MDT"
2956
2957         pool_add $TESTNAME || error "pool_add failed"
2958         do_facet mgs "$LCTL pool_list $FSNAME" |
2959                 grep -Fx "${FSNAME}.${TESTNAME}" ||
2960                 error "lctl pool_list on MGS failed"
2961 }
2962 run_test 27N "lctl pool_list on separate MGS gives correct pool name"
2963
2964 # createtest also checks that device nodes are created and
2965 # then visible correctly (#2091)
2966 test_28() { # bug 2091
2967         test_mkdir $DIR/d28
2968         $CREATETEST $DIR/d28/ct || error "createtest failed"
2969 }
2970 run_test 28 "create/mknod/mkdir with bad file types ============"
2971
2972 test_29() {
2973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2974
2975         sync; sleep 1; sync # flush out any dirty pages from previous tests
2976         cancel_lru_locks
2977         test_mkdir $DIR/d29
2978         touch $DIR/d29/foo
2979         log 'first d29'
2980         ls -l $DIR/d29
2981
2982         declare -i LOCKCOUNTORIG=0
2983         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2984                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2985         done
2986         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2987
2988         declare -i LOCKUNUSEDCOUNTORIG=0
2989         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2990                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2991         done
2992
2993         log 'second d29'
2994         ls -l $DIR/d29
2995         log 'done'
2996
2997         declare -i LOCKCOUNTCURRENT=0
2998         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2999                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3000         done
3001
3002         declare -i LOCKUNUSEDCOUNTCURRENT=0
3003         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3004                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3005         done
3006
3007         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3008                 $LCTL set_param -n ldlm.dump_namespaces ""
3009                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3010                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3011                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3012                 return 2
3013         fi
3014         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3015                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3016                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3017                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3018                 return 3
3019         fi
3020 }
3021 run_test 29 "IT_GETATTR regression  ============================"
3022
3023 test_30a() { # was test_30
3024         cp $(which ls) $DIR || cp /bin/ls $DIR
3025         $DIR/ls / || error "Can't execute binary from lustre"
3026         rm $DIR/ls
3027 }
3028 run_test 30a "execute binary from Lustre (execve) =============="
3029
3030 test_30b() {
3031         cp `which ls` $DIR || cp /bin/ls $DIR
3032         chmod go+rx $DIR/ls
3033         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3034         rm $DIR/ls
3035 }
3036 run_test 30b "execute binary from Lustre as non-root ==========="
3037
3038 test_30c() { # b=22376
3039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3040
3041         cp `which ls` $DIR || cp /bin/ls $DIR
3042         chmod a-rw $DIR/ls
3043         cancel_lru_locks mdc
3044         cancel_lru_locks osc
3045         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3046         rm -f $DIR/ls
3047 }
3048 run_test 30c "execute binary from Lustre without read perms ===="
3049
3050 test_31a() {
3051         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3052         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3053 }
3054 run_test 31a "open-unlink file =================================="
3055
3056 test_31b() {
3057         touch $DIR/f31 || error "touch $DIR/f31 failed"
3058         ln $DIR/f31 $DIR/f31b || error "ln failed"
3059         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3060         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3061 }
3062 run_test 31b "unlink file with multiple links while open ======="
3063
3064 test_31c() {
3065         touch $DIR/f31 || error "touch $DIR/f31 failed"
3066         ln $DIR/f31 $DIR/f31c || error "ln failed"
3067         multiop_bg_pause $DIR/f31 O_uc ||
3068                 error "multiop_bg_pause for $DIR/f31 failed"
3069         MULTIPID=$!
3070         $MULTIOP $DIR/f31c Ouc
3071         kill -USR1 $MULTIPID
3072         wait $MULTIPID
3073 }
3074 run_test 31c "open-unlink file with multiple links ============="
3075
3076 test_31d() {
3077         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3078         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3079 }
3080 run_test 31d "remove of open directory ========================="
3081
3082 test_31e() { # bug 2904
3083         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3084 }
3085 run_test 31e "remove of open non-empty directory ==============="
3086
3087 test_31f() { # bug 4554
3088         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3089
3090         set -vx
3091         test_mkdir $DIR/d31f
3092         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3093         cp /etc/hosts $DIR/d31f
3094         ls -l $DIR/d31f
3095         $LFS getstripe $DIR/d31f/hosts
3096         multiop_bg_pause $DIR/d31f D_c || return 1
3097         MULTIPID=$!
3098
3099         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3100         test_mkdir $DIR/d31f
3101         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3102         cp /etc/hosts $DIR/d31f
3103         ls -l $DIR/d31f
3104         $LFS getstripe $DIR/d31f/hosts
3105         multiop_bg_pause $DIR/d31f D_c || return 1
3106         MULTIPID2=$!
3107
3108         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3109         wait $MULTIPID || error "first opendir $MULTIPID failed"
3110
3111         sleep 6
3112
3113         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3114         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3115         set +vx
3116 }
3117 run_test 31f "remove of open directory with open-unlink file ==="
3118
3119 test_31g() {
3120         echo "-- cross directory link --"
3121         test_mkdir -c1 $DIR/${tdir}ga
3122         test_mkdir -c1 $DIR/${tdir}gb
3123         touch $DIR/${tdir}ga/f
3124         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3125         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3126         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3127         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3128         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3129 }
3130 run_test 31g "cross directory link==============="
3131
3132 test_31h() {
3133         echo "-- cross directory link --"
3134         test_mkdir -c1 $DIR/${tdir}
3135         test_mkdir -c1 $DIR/${tdir}/dir
3136         touch $DIR/${tdir}/f
3137         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3138         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3139         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3140         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3141         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3142 }
3143 run_test 31h "cross directory link under child==============="
3144
3145 test_31i() {
3146         echo "-- cross directory link --"
3147         test_mkdir -c1 $DIR/$tdir
3148         test_mkdir -c1 $DIR/$tdir/dir
3149         touch $DIR/$tdir/dir/f
3150         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3151         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3152         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3153         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3154         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3155 }
3156 run_test 31i "cross directory link under parent==============="
3157
3158 test_31j() {
3159         test_mkdir -c1 -p $DIR/$tdir
3160         test_mkdir -c1 -p $DIR/$tdir/dir1
3161         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3162         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3163         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3164         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3165         return 0
3166 }
3167 run_test 31j "link for directory==============="
3168
3169 test_31k() {
3170         test_mkdir -c1 -p $DIR/$tdir
3171         touch $DIR/$tdir/s
3172         touch $DIR/$tdir/exist
3173         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3174         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3175         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3176         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3177         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3178         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3179         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3180         return 0
3181 }
3182 run_test 31k "link to file: the same, non-existing, dir==============="
3183
3184 test_31m() {
3185         mkdir $DIR/d31m
3186         touch $DIR/d31m/s
3187         mkdir $DIR/d31m2
3188         touch $DIR/d31m2/exist
3189         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3190         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3191         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3192         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3193         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3194         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3195         return 0
3196 }
3197 run_test 31m "link to file: the same, non-existing, dir==============="
3198
3199 test_31n() {
3200         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3201         nlink=$(stat --format=%h $DIR/$tfile)
3202         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3203         local fd=$(free_fd)
3204         local cmd="exec $fd<$DIR/$tfile"
3205         eval $cmd
3206         cmd="exec $fd<&-"
3207         trap "eval $cmd" EXIT
3208         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3209         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3210         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3211         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3212         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3213         eval $cmd
3214 }
3215 run_test 31n "check link count of unlinked file"
3216
3217 link_one() {
3218         local tempfile=$(mktemp $1_XXXXXX)
3219         mlink $tempfile $1 2> /dev/null &&
3220                 echo "$BASHPID: link $tempfile to $1 succeeded"
3221         munlink $tempfile
3222 }
3223
3224 test_31o() { # LU-2901
3225         test_mkdir $DIR/$tdir
3226         for LOOP in $(seq 100); do
3227                 rm -f $DIR/$tdir/$tfile*
3228                 for THREAD in $(seq 8); do
3229                         link_one $DIR/$tdir/$tfile.$LOOP &
3230                 done
3231                 wait
3232                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3233                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3234                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3235                         break || true
3236         done
3237 }
3238 run_test 31o "duplicate hard links with same filename"
3239
3240 test_31p() {
3241         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3242
3243         test_mkdir $DIR/$tdir
3244         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3245         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3246
3247         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3248                 error "open unlink test1 failed"
3249         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3250                 error "open unlink test2 failed"
3251
3252         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3253                 error "test1 still exists"
3254         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3255                 error "test2 still exists"
3256 }
3257 run_test 31p "remove of open striped directory"
3258
3259 cleanup_test32_mount() {
3260         local rc=0
3261         trap 0
3262         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3263         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3264         losetup -d $loopdev || true
3265         rm -rf $DIR/$tdir
3266         return $rc
3267 }
3268
3269 test_32a() {
3270         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3271
3272         echo "== more mountpoints and symlinks ================="
3273         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3274         trap cleanup_test32_mount EXIT
3275         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3276         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3277                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3278         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3279                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3280         cleanup_test32_mount
3281 }
3282 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3283
3284 test_32b() {
3285         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3286
3287         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3288         trap cleanup_test32_mount EXIT
3289         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3290         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3291                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3292         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3293                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3294         cleanup_test32_mount
3295 }
3296 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3297
3298 test_32c() {
3299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3300
3301         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3302         trap cleanup_test32_mount EXIT
3303         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3304         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3305                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3306         test_mkdir -p $DIR/$tdir/d2/test_dir
3307         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3308                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3309         cleanup_test32_mount
3310 }
3311 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3312
3313 test_32d() {
3314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3315
3316         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3317         trap cleanup_test32_mount EXIT
3318         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3319         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3320                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3321         test_mkdir -p $DIR/$tdir/d2/test_dir
3322         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3323                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3324         cleanup_test32_mount
3325 }
3326 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3327
3328 test_32e() {
3329         rm -fr $DIR/$tdir
3330         test_mkdir -p $DIR/$tdir/tmp
3331         local tmp_dir=$DIR/$tdir/tmp
3332         ln -s $DIR/$tdir $tmp_dir/symlink11
3333         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3334         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3335         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3336 }
3337 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3338
3339 test_32f() {
3340         rm -fr $DIR/$tdir
3341         test_mkdir -p $DIR/$tdir/tmp
3342         local tmp_dir=$DIR/$tdir/tmp
3343         ln -s $DIR/$tdir $tmp_dir/symlink11
3344         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3345         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3346         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3347 }
3348 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3349
3350 test_32g() {
3351         local tmp_dir=$DIR/$tdir/tmp
3352         test_mkdir -p $tmp_dir
3353         test_mkdir $DIR/${tdir}2
3354         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3355         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3356         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3357         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3358         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3359         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3360 }
3361 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3362
3363 test_32h() {
3364         rm -fr $DIR/$tdir $DIR/${tdir}2
3365         tmp_dir=$DIR/$tdir/tmp
3366         test_mkdir -p $tmp_dir
3367         test_mkdir $DIR/${tdir}2
3368         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3369         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3370         ls $tmp_dir/symlink12 || error "listing symlink12"
3371         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3372 }
3373 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3374
3375 test_32i() {
3376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3377
3378         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3379         trap cleanup_test32_mount EXIT
3380         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3381         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3382                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3383         touch $DIR/$tdir/test_file
3384         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3385                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3386         cleanup_test32_mount
3387 }
3388 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3389
3390 test_32j() {
3391         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3392
3393         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3394         trap cleanup_test32_mount EXIT
3395         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3396         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3397                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3398         touch $DIR/$tdir/test_file
3399         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3400                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3401         cleanup_test32_mount
3402 }
3403 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3404
3405 test_32k() {
3406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3407
3408         rm -fr $DIR/$tdir
3409         trap cleanup_test32_mount EXIT
3410         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3411         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3412                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3413         test_mkdir -p $DIR/$tdir/d2
3414         touch $DIR/$tdir/d2/test_file || error "touch failed"
3415         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3416                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3417         cleanup_test32_mount
3418 }
3419 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3420
3421 test_32l() {
3422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3423
3424         rm -fr $DIR/$tdir
3425         trap cleanup_test32_mount EXIT
3426         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3427         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3428                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3429         test_mkdir -p $DIR/$tdir/d2
3430         touch $DIR/$tdir/d2/test_file || error "touch failed"
3431         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3432                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3433         cleanup_test32_mount
3434 }
3435 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3436
3437 test_32m() {
3438         rm -fr $DIR/d32m
3439         test_mkdir -p $DIR/d32m/tmp
3440         TMP_DIR=$DIR/d32m/tmp
3441         ln -s $DIR $TMP_DIR/symlink11
3442         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3443         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3444                 error "symlink11 not a link"
3445         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3446                 error "symlink01 not a link"
3447 }
3448 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3449
3450 test_32n() {
3451         rm -fr $DIR/d32n
3452         test_mkdir -p $DIR/d32n/tmp
3453         TMP_DIR=$DIR/d32n/tmp
3454         ln -s $DIR $TMP_DIR/symlink11
3455         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3456         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3457         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3458 }
3459 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3460
3461 test_32o() {
3462         touch $DIR/$tfile
3463         test_mkdir -p $DIR/d32o/tmp
3464         TMP_DIR=$DIR/d32o/tmp
3465         ln -s $DIR/$tfile $TMP_DIR/symlink12
3466         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3467         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3468                 error "symlink12 not a link"
3469         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3470         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3471                 error "$DIR/d32o/tmp/symlink12 not file type"
3472         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3473                 error "$DIR/d32o/symlink02 not file type"
3474 }
3475 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3476
3477 test_32p() {
3478         log 32p_1
3479         rm -fr $DIR/d32p
3480         log 32p_2
3481         rm -f $DIR/$tfile
3482         log 32p_3
3483         touch $DIR/$tfile
3484         log 32p_4
3485         test_mkdir -p $DIR/d32p/tmp
3486         log 32p_5
3487         TMP_DIR=$DIR/d32p/tmp
3488         log 32p_6
3489         ln -s $DIR/$tfile $TMP_DIR/symlink12
3490         log 32p_7
3491         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3492         log 32p_8
3493         cat $DIR/d32p/tmp/symlink12 ||
3494                 error "Can't open $DIR/d32p/tmp/symlink12"
3495         log 32p_9
3496         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3497         log 32p_10
3498 }
3499 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3500
3501 test_32q() {
3502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3503
3504         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3505         trap cleanup_test32_mount EXIT
3506         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3507         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3508         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3509                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3510         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3511         cleanup_test32_mount
3512 }
3513 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3514
3515 test_32r() {
3516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3517
3518         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3519         trap cleanup_test32_mount EXIT
3520         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3521         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3522         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3523                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3524         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3525         cleanup_test32_mount
3526 }
3527 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3528
3529 test_33aa() {
3530         rm -f $DIR/$tfile
3531         touch $DIR/$tfile
3532         chmod 444 $DIR/$tfile
3533         chown $RUNAS_ID $DIR/$tfile
3534         log 33_1
3535         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3536         log 33_2
3537 }
3538 run_test 33aa "write file with mode 444 (should return error)"
3539
3540 test_33a() {
3541         rm -fr $DIR/$tdir
3542         test_mkdir $DIR/$tdir
3543         chown $RUNAS_ID $DIR/$tdir
3544         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3545                 error "$RUNAS create $tdir/$tfile failed"
3546         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3547                 error "open RDWR" || true
3548 }
3549 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3550
3551 test_33b() {
3552         rm -fr $DIR/$tdir
3553         test_mkdir $DIR/$tdir
3554         chown $RUNAS_ID $DIR/$tdir
3555         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3556 }
3557 run_test 33b "test open file with malformed flags (No panic)"
3558
3559 test_33c() {
3560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3561         remote_ost_nodsh && skip "remote OST with nodsh"
3562
3563         local ostnum
3564         local ostname
3565         local write_bytes
3566         local all_zeros
3567
3568         all_zeros=:
3569         rm -fr $DIR/$tdir
3570         test_mkdir $DIR/$tdir
3571         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3572
3573         sync
3574         for ostnum in $(seq $OSTCOUNT); do
3575                 # test-framework's OST numbering is one-based, while Lustre's
3576                 # is zero-based
3577                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3578                 # Parsing llobdstat's output sucks; we could grep the /proc
3579                 # path, but that's likely to not be as portable as using the
3580                 # llobdstat utility.  So we parse lctl output instead.
3581                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3582                         obdfilter/$ostname/stats |
3583                         awk '/^write_bytes/ {print $7}' )
3584                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3585                 if (( ${write_bytes:-0} > 0 ))
3586                 then
3587                         all_zeros=false
3588                         break;
3589                 fi
3590         done
3591
3592         $all_zeros || return 0
3593
3594         # Write four bytes
3595         echo foo > $DIR/$tdir/bar
3596         # Really write them
3597         sync
3598
3599         # Total up write_bytes after writing.  We'd better find non-zeros.
3600         for ostnum in $(seq $OSTCOUNT); do
3601                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3602                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3603                         obdfilter/$ostname/stats |
3604                         awk '/^write_bytes/ {print $7}' )
3605                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3606                 if (( ${write_bytes:-0} > 0 ))
3607                 then
3608                         all_zeros=false
3609                         break;
3610                 fi
3611         done
3612
3613         if $all_zeros
3614         then
3615                 for ostnum in $(seq $OSTCOUNT); do
3616                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3617                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3618                         do_facet ost$ostnum lctl get_param -n \
3619                                 obdfilter/$ostname/stats
3620                 done
3621                 error "OST not keeping write_bytes stats (b22312)"
3622         fi
3623 }
3624 run_test 33c "test llobdstat and write_bytes"
3625
3626 test_33d() {
3627         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3629
3630         local MDTIDX=1
3631         local remote_dir=$DIR/$tdir/remote_dir
3632
3633         test_mkdir $DIR/$tdir
3634         $LFS mkdir -i $MDTIDX $remote_dir ||
3635                 error "create remote directory failed"
3636
3637         touch $remote_dir/$tfile
3638         chmod 444 $remote_dir/$tfile
3639         chown $RUNAS_ID $remote_dir/$tfile
3640
3641         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3642
3643         chown $RUNAS_ID $remote_dir
3644         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3645                                         error "create" || true
3646         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3647                                     error "open RDWR" || true
3648         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3649 }
3650 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3651
3652 test_33e() {
3653         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3654
3655         mkdir $DIR/$tdir
3656
3657         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3658         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3659         mkdir $DIR/$tdir/local_dir
3660
3661         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3662         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3663         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3664
3665         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3666                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3667
3668         rmdir $DIR/$tdir/* || error "rmdir failed"
3669
3670         umask 777
3671         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3672         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3673         mkdir $DIR/$tdir/local_dir
3674
3675         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3676         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3677         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3678
3679         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3680                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3681
3682         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3683
3684         umask 000
3685         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3686         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3687         mkdir $DIR/$tdir/local_dir
3688
3689         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3690         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3691         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3692
3693         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3694                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3695 }
3696 run_test 33e "mkdir and striped directory should have same mode"
3697
3698 cleanup_33f() {
3699         trap 0
3700         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3701 }
3702
3703 test_33f() {
3704         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3705         remote_mds_nodsh && skip "remote MDS with nodsh"
3706
3707         mkdir $DIR/$tdir
3708         chmod go+rwx $DIR/$tdir
3709         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3710         trap cleanup_33f EXIT
3711
3712         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3713                 error "cannot create striped directory"
3714
3715         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3716                 error "cannot create files in striped directory"
3717
3718         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3719                 error "cannot remove files in striped directory"
3720
3721         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3722                 error "cannot remove striped directory"
3723
3724         cleanup_33f
3725 }
3726 run_test 33f "nonroot user can create, access, and remove a striped directory"
3727
3728 test_33g() {
3729         mkdir -p $DIR/$tdir/dir2
3730
3731         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3732         echo $err
3733         [[ $err =~ "exists" ]] || error "Not exists error"
3734 }
3735 run_test 33g "nonroot user create already existing root created file"
3736
3737 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3738 test_34a() {
3739         rm -f $DIR/f34
3740         $MCREATE $DIR/f34 || error "mcreate failed"
3741         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3742                 error "getstripe failed"
3743         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3744         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3745                 error "getstripe failed"
3746         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3747                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3748 }
3749 run_test 34a "truncate file that has not been opened ==========="
3750
3751 test_34b() {
3752         [ ! -f $DIR/f34 ] && test_34a
3753         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3754                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3755         $OPENFILE -f O_RDONLY $DIR/f34
3756         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3757                 error "getstripe failed"
3758         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3759                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3760 }
3761 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3762
3763 test_34c() {
3764         [ ! -f $DIR/f34 ] && test_34a
3765         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3766                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3767         $OPENFILE -f O_RDWR $DIR/f34
3768         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3769                 error "$LFS getstripe failed"
3770         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3771                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3772 }
3773 run_test 34c "O_RDWR opening file-with-size works =============="
3774
3775 test_34d() {
3776         [ ! -f $DIR/f34 ] && test_34a
3777         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3778                 error "dd failed"
3779         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3780                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3781         rm $DIR/f34
3782 }
3783 run_test 34d "write to sparse file ============================="
3784
3785 test_34e() {
3786         rm -f $DIR/f34e
3787         $MCREATE $DIR/f34e || error "mcreate failed"
3788         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3789         $CHECKSTAT -s 1000 $DIR/f34e ||
3790                 error "Size of $DIR/f34e not equal to 1000 bytes"
3791         $OPENFILE -f O_RDWR $DIR/f34e
3792         $CHECKSTAT -s 1000 $DIR/f34e ||
3793                 error "Size of $DIR/f34e not equal to 1000 bytes"
3794 }
3795 run_test 34e "create objects, some with size and some without =="
3796
3797 test_34f() { # bug 6242, 6243
3798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3799
3800         SIZE34F=48000
3801         rm -f $DIR/f34f
3802         $MCREATE $DIR/f34f || error "mcreate failed"
3803         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3804         dd if=$DIR/f34f of=$TMP/f34f
3805         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3806         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3807         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3808         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3809         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3810 }
3811 run_test 34f "read from a file with no objects until EOF ======="
3812
3813 test_34g() {
3814         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3815
3816         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3817                 error "dd failed"
3818         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3819         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3820                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3821         cancel_lru_locks osc
3822         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3823                 error "wrong size after lock cancel"
3824
3825         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3826         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3827                 error "expanding truncate failed"
3828         cancel_lru_locks osc
3829         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3830                 error "wrong expanded size after lock cancel"
3831 }
3832 run_test 34g "truncate long file ==============================="
3833
3834 test_34h() {
3835         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3836
3837         local gid=10
3838         local sz=1000
3839
3840         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3841         sync # Flush the cache so that multiop below does not block on cache
3842              # flush when getting the group lock
3843         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3844         MULTIPID=$!
3845
3846         # Since just timed wait is not good enough, let's do a sync write
3847         # that way we are sure enough time for a roundtrip + processing
3848         # passed + 2 seconds of extra margin.
3849         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3850         rm $DIR/${tfile}-1
3851         sleep 2
3852
3853         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3854                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3855                 kill -9 $MULTIPID
3856         fi
3857         wait $MULTIPID
3858         local nsz=`stat -c %s $DIR/$tfile`
3859         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3860 }
3861 run_test 34h "ftruncate file under grouplock should not block"
3862
3863 test_35a() {
3864         cp /bin/sh $DIR/f35a
3865         chmod 444 $DIR/f35a
3866         chown $RUNAS_ID $DIR/f35a
3867         $RUNAS $DIR/f35a && error || true
3868         rm $DIR/f35a
3869 }
3870 run_test 35a "exec file with mode 444 (should return and not leak)"
3871
3872 test_36a() {
3873         rm -f $DIR/f36
3874         utime $DIR/f36 || error "utime failed for MDS"
3875 }
3876 run_test 36a "MDS utime check (mknod, utime)"
3877
3878 test_36b() {
3879         echo "" > $DIR/f36
3880         utime $DIR/f36 || error "utime failed for OST"
3881 }
3882 run_test 36b "OST utime check (open, utime)"
3883
3884 test_36c() {
3885         rm -f $DIR/d36/f36
3886         test_mkdir $DIR/d36
3887         chown $RUNAS_ID $DIR/d36
3888         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3889 }
3890 run_test 36c "non-root MDS utime check (mknod, utime)"
3891
3892 test_36d() {
3893         [ ! -d $DIR/d36 ] && test_36c
3894         echo "" > $DIR/d36/f36
3895         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3896 }
3897 run_test 36d "non-root OST utime check (open, utime)"
3898
3899 test_36e() {
3900         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3901
3902         test_mkdir $DIR/$tdir
3903         touch $DIR/$tdir/$tfile
3904         $RUNAS utime $DIR/$tdir/$tfile &&
3905                 error "utime worked, expected failure" || true
3906 }
3907 run_test 36e "utime on non-owned file (should return error)"
3908
3909 subr_36fh() {
3910         local fl="$1"
3911         local LANG_SAVE=$LANG
3912         local LC_LANG_SAVE=$LC_LANG
3913         export LANG=C LC_LANG=C # for date language
3914
3915         DATESTR="Dec 20  2000"
3916         test_mkdir $DIR/$tdir
3917         lctl set_param fail_loc=$fl
3918         date; date +%s
3919         cp /etc/hosts $DIR/$tdir/$tfile
3920         sync & # write RPC generated with "current" inode timestamp, but delayed
3921         sleep 1
3922         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3923         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3924         cancel_lru_locks $OSC
3925         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3926         date; date +%s
3927         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3928                 echo "BEFORE: $LS_BEFORE" && \
3929                 echo "AFTER : $LS_AFTER" && \
3930                 echo "WANT  : $DATESTR" && \
3931                 error "$DIR/$tdir/$tfile timestamps changed" || true
3932
3933         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3934 }
3935
3936 test_36f() {
3937         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3938
3939         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3940         subr_36fh "0x80000214"
3941 }
3942 run_test 36f "utime on file racing with OST BRW write =========="
3943
3944 test_36g() {
3945         remote_ost_nodsh && skip "remote OST with nodsh"
3946         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3947         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3948                 skip "Need MDS version at least 2.12.51"
3949
3950         local fmd_max_age
3951         local fmd
3952         local facet="ost1"
3953         local tgt="obdfilter"
3954
3955         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3956
3957         test_mkdir $DIR/$tdir
3958         fmd_max_age=$(do_facet $facet \
3959                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3960                 head -n 1")
3961
3962         echo "FMD max age: ${fmd_max_age}s"
3963         touch $DIR/$tdir/$tfile
3964         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3965                 gawk '{cnt=cnt+$1}  END{print cnt}')
3966         echo "FMD before: $fmd"
3967         [[ $fmd == 0 ]] &&
3968                 error "FMD wasn't create by touch"
3969         sleep $((fmd_max_age + 12))
3970         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3971                 gawk '{cnt=cnt+$1}  END{print cnt}')
3972         echo "FMD after: $fmd"
3973         [[ $fmd == 0 ]] ||
3974                 error "FMD wasn't expired by ping"
3975 }
3976 run_test 36g "FMD cache expiry ====================="
3977
3978 test_36h() {
3979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3980
3981         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3982         subr_36fh "0x80000227"
3983 }
3984 run_test 36h "utime on file racing with OST BRW write =========="
3985
3986 test_36i() {
3987         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3988
3989         test_mkdir $DIR/$tdir
3990         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3991
3992         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3993         local new_mtime=$((mtime + 200))
3994
3995         #change Modify time of striped dir
3996         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3997                         error "change mtime failed"
3998
3999         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4000
4001         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4002 }
4003 run_test 36i "change mtime on striped directory"
4004
4005 # test_37 - duplicate with tests 32q 32r
4006
4007 test_38() {
4008         local file=$DIR/$tfile
4009         touch $file
4010         openfile -f O_DIRECTORY $file
4011         local RC=$?
4012         local ENOTDIR=20
4013         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4014         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4015 }
4016 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4017
4018 test_39a() { # was test_39
4019         touch $DIR/$tfile
4020         touch $DIR/${tfile}2
4021 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4022 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4023 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4024         sleep 2
4025         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4026         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4027                 echo "mtime"
4028                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4029                 echo "atime"
4030                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4031                 echo "ctime"
4032                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4033                 error "O_TRUNC didn't change timestamps"
4034         fi
4035 }
4036 run_test 39a "mtime changed on create"
4037
4038 test_39b() {
4039         test_mkdir -c1 $DIR/$tdir
4040         cp -p /etc/passwd $DIR/$tdir/fopen
4041         cp -p /etc/passwd $DIR/$tdir/flink
4042         cp -p /etc/passwd $DIR/$tdir/funlink
4043         cp -p /etc/passwd $DIR/$tdir/frename
4044         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4045
4046         sleep 1
4047         echo "aaaaaa" >> $DIR/$tdir/fopen
4048         echo "aaaaaa" >> $DIR/$tdir/flink
4049         echo "aaaaaa" >> $DIR/$tdir/funlink
4050         echo "aaaaaa" >> $DIR/$tdir/frename
4051
4052         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4053         local link_new=`stat -c %Y $DIR/$tdir/flink`
4054         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4055         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4056
4057         cat $DIR/$tdir/fopen > /dev/null
4058         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4059         rm -f $DIR/$tdir/funlink2
4060         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4061
4062         for (( i=0; i < 2; i++ )) ; do
4063                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4064                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4065                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4066                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4067
4068                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4069                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4070                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4071                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4072
4073                 cancel_lru_locks $OSC
4074                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4075         done
4076 }
4077 run_test 39b "mtime change on open, link, unlink, rename  ======"
4078
4079 # this should be set to past
4080 TEST_39_MTIME=`date -d "1 year ago" +%s`
4081
4082 # bug 11063
4083 test_39c() {
4084         touch $DIR1/$tfile
4085         sleep 2
4086         local mtime0=`stat -c %Y $DIR1/$tfile`
4087
4088         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4089         local mtime1=`stat -c %Y $DIR1/$tfile`
4090         [ "$mtime1" = $TEST_39_MTIME ] || \
4091                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4092
4093         local d1=`date +%s`
4094         echo hello >> $DIR1/$tfile
4095         local d2=`date +%s`
4096         local mtime2=`stat -c %Y $DIR1/$tfile`
4097         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4098                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4099
4100         mv $DIR1/$tfile $DIR1/$tfile-1
4101
4102         for (( i=0; i < 2; i++ )) ; do
4103                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4104                 [ "$mtime2" = "$mtime3" ] || \
4105                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4106
4107                 cancel_lru_locks $OSC
4108                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4109         done
4110 }
4111 run_test 39c "mtime change on rename ==========================="
4112
4113 # bug 21114
4114 test_39d() {
4115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4116
4117         touch $DIR1/$tfile
4118         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4119
4120         for (( i=0; i < 2; i++ )) ; do
4121                 local mtime=`stat -c %Y $DIR1/$tfile`
4122                 [ $mtime = $TEST_39_MTIME ] || \
4123                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4124
4125                 cancel_lru_locks $OSC
4126                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4127         done
4128 }
4129 run_test 39d "create, utime, stat =============================="
4130
4131 # bug 21114
4132 test_39e() {
4133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4134
4135         touch $DIR1/$tfile
4136         local mtime1=`stat -c %Y $DIR1/$tfile`
4137
4138         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4139
4140         for (( i=0; i < 2; i++ )) ; do
4141                 local mtime2=`stat -c %Y $DIR1/$tfile`
4142                 [ $mtime2 = $TEST_39_MTIME ] || \
4143                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4144
4145                 cancel_lru_locks $OSC
4146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4147         done
4148 }
4149 run_test 39e "create, stat, utime, stat ========================"
4150
4151 # bug 21114
4152 test_39f() {
4153         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4154
4155         touch $DIR1/$tfile
4156         mtime1=`stat -c %Y $DIR1/$tfile`
4157
4158         sleep 2
4159         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4160
4161         for (( i=0; i < 2; i++ )) ; do
4162                 local mtime2=`stat -c %Y $DIR1/$tfile`
4163                 [ $mtime2 = $TEST_39_MTIME ] || \
4164                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4165
4166                 cancel_lru_locks $OSC
4167                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4168         done
4169 }
4170 run_test 39f "create, stat, sleep, utime, stat ================="
4171
4172 # bug 11063
4173 test_39g() {
4174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4175
4176         echo hello >> $DIR1/$tfile
4177         local mtime1=`stat -c %Y $DIR1/$tfile`
4178
4179         sleep 2
4180         chmod o+r $DIR1/$tfile
4181
4182         for (( i=0; i < 2; i++ )) ; do
4183                 local mtime2=`stat -c %Y $DIR1/$tfile`
4184                 [ "$mtime1" = "$mtime2" ] || \
4185                         error "lost mtime: $mtime2, should be $mtime1"
4186
4187                 cancel_lru_locks $OSC
4188                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4189         done
4190 }
4191 run_test 39g "write, chmod, stat ==============================="
4192
4193 # bug 11063
4194 test_39h() {
4195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4196
4197         touch $DIR1/$tfile
4198         sleep 1
4199
4200         local d1=`date`
4201         echo hello >> $DIR1/$tfile
4202         local mtime1=`stat -c %Y $DIR1/$tfile`
4203
4204         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4205         local d2=`date`
4206         if [ "$d1" != "$d2" ]; then
4207                 echo "write and touch not within one second"
4208         else
4209                 for (( i=0; i < 2; i++ )) ; do
4210                         local mtime2=`stat -c %Y $DIR1/$tfile`
4211                         [ "$mtime2" = $TEST_39_MTIME ] || \
4212                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4213
4214                         cancel_lru_locks $OSC
4215                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4216                 done
4217         fi
4218 }
4219 run_test 39h "write, utime within one second, stat ============="
4220
4221 test_39i() {
4222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4223
4224         touch $DIR1/$tfile
4225         sleep 1
4226
4227         echo hello >> $DIR1/$tfile
4228         local mtime1=`stat -c %Y $DIR1/$tfile`
4229
4230         mv $DIR1/$tfile $DIR1/$tfile-1
4231
4232         for (( i=0; i < 2; i++ )) ; do
4233                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4234
4235                 [ "$mtime1" = "$mtime2" ] || \
4236                         error "lost mtime: $mtime2, should be $mtime1"
4237
4238                 cancel_lru_locks $OSC
4239                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4240         done
4241 }
4242 run_test 39i "write, rename, stat =============================="
4243
4244 test_39j() {
4245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4246
4247         start_full_debug_logging
4248         touch $DIR1/$tfile
4249         sleep 1
4250
4251         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4252         lctl set_param fail_loc=0x80000412
4253         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4254                 error "multiop failed"
4255         local multipid=$!
4256         local mtime1=`stat -c %Y $DIR1/$tfile`
4257
4258         mv $DIR1/$tfile $DIR1/$tfile-1
4259
4260         kill -USR1 $multipid
4261         wait $multipid || error "multiop close failed"
4262
4263         for (( i=0; i < 2; i++ )) ; do
4264                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4265                 [ "$mtime1" = "$mtime2" ] ||
4266                         error "mtime is lost on close: $mtime2, " \
4267                               "should be $mtime1"
4268
4269                 cancel_lru_locks $OSC
4270                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4271         done
4272         lctl set_param fail_loc=0
4273         stop_full_debug_logging
4274 }
4275 run_test 39j "write, rename, close, stat ======================="
4276
4277 test_39k() {
4278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4279
4280         touch $DIR1/$tfile
4281         sleep 1
4282
4283         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4284         local multipid=$!
4285         local mtime1=`stat -c %Y $DIR1/$tfile`
4286
4287         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4288
4289         kill -USR1 $multipid
4290         wait $multipid || error "multiop close failed"
4291
4292         for (( i=0; i < 2; i++ )) ; do
4293                 local mtime2=`stat -c %Y $DIR1/$tfile`
4294
4295                 [ "$mtime2" = $TEST_39_MTIME ] || \
4296                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4297
4298                 cancel_lru_locks osc
4299                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4300         done
4301 }
4302 run_test 39k "write, utime, close, stat ========================"
4303
4304 # this should be set to future
4305 TEST_39_ATIME=`date -d "1 year" +%s`
4306
4307 test_39l() {
4308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4309         remote_mds_nodsh && skip "remote MDS with nodsh"
4310
4311         local atime_diff=$(do_facet $SINGLEMDS \
4312                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4313         rm -rf $DIR/$tdir
4314         mkdir -p $DIR/$tdir
4315
4316         # test setting directory atime to future
4317         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4318         local atime=$(stat -c %X $DIR/$tdir)
4319         [ "$atime" = $TEST_39_ATIME ] ||
4320                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4321
4322         # test setting directory atime from future to now
4323         local now=$(date +%s)
4324         touch -a -d @$now $DIR/$tdir
4325
4326         atime=$(stat -c %X $DIR/$tdir)
4327         [ "$atime" -eq "$now"  ] ||
4328                 error "atime is not updated from future: $atime, $now"
4329
4330         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4331         sleep 3
4332
4333         # test setting directory atime when now > dir atime + atime_diff
4334         local d1=$(date +%s)
4335         ls $DIR/$tdir
4336         local d2=$(date +%s)
4337         cancel_lru_locks mdc
4338         atime=$(stat -c %X $DIR/$tdir)
4339         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4340                 error "atime is not updated  : $atime, should be $d2"
4341
4342         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4343         sleep 3
4344
4345         # test not setting directory atime when now < dir atime + atime_diff
4346         ls $DIR/$tdir
4347         cancel_lru_locks mdc
4348         atime=$(stat -c %X $DIR/$tdir)
4349         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4350                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4351
4352         do_facet $SINGLEMDS \
4353                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4354 }
4355 run_test 39l "directory atime update ==========================="
4356
4357 test_39m() {
4358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4359
4360         touch $DIR1/$tfile
4361         sleep 2
4362         local far_past_mtime=$(date -d "May 29 1953" +%s)
4363         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4364
4365         touch -m -d @$far_past_mtime $DIR1/$tfile
4366         touch -a -d @$far_past_atime $DIR1/$tfile
4367
4368         for (( i=0; i < 2; i++ )) ; do
4369                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4370                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4371                         error "atime or mtime set incorrectly"
4372
4373                 cancel_lru_locks $OSC
4374                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4375         done
4376 }
4377 run_test 39m "test atime and mtime before 1970"
4378
4379 test_39n() { # LU-3832
4380         remote_mds_nodsh && skip "remote MDS with nodsh"
4381
4382         local atime_diff=$(do_facet $SINGLEMDS \
4383                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4384         local atime0
4385         local atime1
4386         local atime2
4387
4388         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4389
4390         rm -rf $DIR/$tfile
4391         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4392         atime0=$(stat -c %X $DIR/$tfile)
4393
4394         sleep 5
4395         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4396         atime1=$(stat -c %X $DIR/$tfile)
4397
4398         sleep 5
4399         cancel_lru_locks mdc
4400         cancel_lru_locks osc
4401         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4402         atime2=$(stat -c %X $DIR/$tfile)
4403
4404         do_facet $SINGLEMDS \
4405                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4406
4407         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4408         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4409 }
4410 run_test 39n "check that O_NOATIME is honored"
4411
4412 test_39o() {
4413         TESTDIR=$DIR/$tdir/$tfile
4414         [ -e $TESTDIR ] && rm -rf $TESTDIR
4415         mkdir -p $TESTDIR
4416         cd $TESTDIR
4417         links1=2
4418         ls
4419         mkdir a b
4420         ls
4421         links2=$(stat -c %h .)
4422         [ $(($links1 + 2)) != $links2 ] &&
4423                 error "wrong links count $(($links1 + 2)) != $links2"
4424         rmdir b
4425         links3=$(stat -c %h .)
4426         [ $(($links1 + 1)) != $links3 ] &&
4427                 error "wrong links count $links1 != $links3"
4428         return 0
4429 }
4430 run_test 39o "directory cached attributes updated after create"
4431
4432 test_39p() {
4433         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4434
4435         local MDTIDX=1
4436         TESTDIR=$DIR/$tdir/$tdir
4437         [ -e $TESTDIR ] && rm -rf $TESTDIR
4438         test_mkdir -p $TESTDIR
4439         cd $TESTDIR
4440         links1=2
4441         ls
4442         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4443         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4444         ls
4445         links2=$(stat -c %h .)
4446         [ $(($links1 + 2)) != $links2 ] &&
4447                 error "wrong links count $(($links1 + 2)) != $links2"
4448         rmdir remote_dir2
4449         links3=$(stat -c %h .)
4450         [ $(($links1 + 1)) != $links3 ] &&
4451                 error "wrong links count $links1 != $links3"
4452         return 0
4453 }
4454 run_test 39p "remote directory cached attributes updated after create ========"
4455
4456
4457 test_39q() { # LU-8041
4458         local testdir=$DIR/$tdir
4459         mkdir -p $testdir
4460         multiop_bg_pause $testdir D_c || error "multiop failed"
4461         local multipid=$!
4462         cancel_lru_locks mdc
4463         kill -USR1 $multipid
4464         local atime=$(stat -c %X $testdir)
4465         [ "$atime" -ne 0 ] || error "atime is zero"
4466 }
4467 run_test 39q "close won't zero out atime"
4468
4469 test_40() {
4470         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4471         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4472                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4473         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4474                 error "$tfile is not 4096 bytes in size"
4475 }
4476 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4477
4478 test_41() {
4479         # bug 1553
4480         small_write $DIR/f41 18
4481 }
4482 run_test 41 "test small file write + fstat ====================="
4483
4484 count_ost_writes() {
4485         lctl get_param -n ${OSC}.*.stats |
4486                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4487                         END { printf("%0.0f", writes) }'
4488 }
4489
4490 # decent default
4491 WRITEBACK_SAVE=500
4492 DIRTY_RATIO_SAVE=40
4493 MAX_DIRTY_RATIO=50
4494 BG_DIRTY_RATIO_SAVE=10
4495 MAX_BG_DIRTY_RATIO=25
4496
4497 start_writeback() {
4498         trap 0
4499         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4500         # dirty_ratio, dirty_background_ratio
4501         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4502                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4503                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4504                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4505         else
4506                 # if file not here, we are a 2.4 kernel
4507                 kill -CONT `pidof kupdated`
4508         fi
4509 }
4510
4511 stop_writeback() {
4512         # setup the trap first, so someone cannot exit the test at the
4513         # exact wrong time and mess up a machine
4514         trap start_writeback EXIT
4515         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4516         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4517                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4518                 sysctl -w vm.dirty_writeback_centisecs=0
4519                 sysctl -w vm.dirty_writeback_centisecs=0
4520                 # save and increase /proc/sys/vm/dirty_ratio
4521                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4522                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4523                 # save and increase /proc/sys/vm/dirty_background_ratio
4524                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4525                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4526         else
4527                 # if file not here, we are a 2.4 kernel
4528                 kill -STOP `pidof kupdated`
4529         fi
4530 }
4531
4532 # ensure that all stripes have some grant before we test client-side cache
4533 setup_test42() {
4534         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4535                 dd if=/dev/zero of=$i bs=4k count=1
4536                 rm $i
4537         done
4538 }
4539
4540 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4541 # file truncation, and file removal.
4542 test_42a() {
4543         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4544
4545         setup_test42
4546         cancel_lru_locks $OSC
4547         stop_writeback
4548         sync; sleep 1; sync # just to be safe
4549         BEFOREWRITES=`count_ost_writes`
4550         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4551         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4552         AFTERWRITES=`count_ost_writes`
4553         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4554                 error "$BEFOREWRITES < $AFTERWRITES"
4555         start_writeback
4556 }
4557 run_test 42a "ensure that we don't flush on close"
4558
4559 test_42b() {
4560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4561
4562         setup_test42
4563         cancel_lru_locks $OSC
4564         stop_writeback
4565         sync
4566         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4567         BEFOREWRITES=$(count_ost_writes)
4568         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4569         AFTERWRITES=$(count_ost_writes)
4570         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4571                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4572         fi
4573         BEFOREWRITES=$(count_ost_writes)
4574         sync || error "sync: $?"
4575         AFTERWRITES=$(count_ost_writes)
4576         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4577                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4578         fi
4579         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4580         start_writeback
4581         return 0
4582 }
4583 run_test 42b "test destroy of file with cached dirty data ======"
4584
4585 # if these tests just want to test the effect of truncation,
4586 # they have to be very careful.  consider:
4587 # - the first open gets a {0,EOF}PR lock
4588 # - the first write conflicts and gets a {0, count-1}PW
4589 # - the rest of the writes are under {count,EOF}PW
4590 # - the open for truncate tries to match a {0,EOF}PR
4591 #   for the filesize and cancels the PWs.
4592 # any number of fixes (don't get {0,EOF} on open, match
4593 # composite locks, do smarter file size management) fix
4594 # this, but for now we want these tests to verify that
4595 # the cancellation with truncate intent works, so we
4596 # start the file with a full-file pw lock to match against
4597 # until the truncate.
4598 trunc_test() {
4599         test=$1
4600         file=$DIR/$test
4601         offset=$2
4602         cancel_lru_locks $OSC
4603         stop_writeback
4604         # prime the file with 0,EOF PW to match
4605         touch $file
4606         $TRUNCATE $file 0
4607         sync; sync
4608         # now the real test..
4609         dd if=/dev/zero of=$file bs=1024 count=100
4610         BEFOREWRITES=`count_ost_writes`
4611         $TRUNCATE $file $offset
4612         cancel_lru_locks $OSC
4613         AFTERWRITES=`count_ost_writes`
4614         start_writeback
4615 }
4616
4617 test_42c() {
4618         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4619
4620         trunc_test 42c 1024
4621         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4622                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4623         rm $file
4624 }
4625 run_test 42c "test partial truncate of file with cached dirty data"
4626
4627 test_42d() {
4628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4629
4630         trunc_test 42d 0
4631         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4632                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4633         rm $file
4634 }
4635 run_test 42d "test complete truncate of file with cached dirty data"
4636
4637 test_42e() { # bug22074
4638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4639
4640         local TDIR=$DIR/${tdir}e
4641         local pages=16 # hardcoded 16 pages, don't change it.
4642         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4643         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4644         local max_dirty_mb
4645         local warmup_files
4646
4647         test_mkdir $DIR/${tdir}e
4648         $LFS setstripe -c 1 $TDIR
4649         createmany -o $TDIR/f $files
4650
4651         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4652
4653         # we assume that with $OSTCOUNT files, at least one of them will
4654         # be allocated on OST0.
4655         warmup_files=$((OSTCOUNT * max_dirty_mb))
4656         createmany -o $TDIR/w $warmup_files
4657
4658         # write a large amount of data into one file and sync, to get good
4659         # avail_grant number from OST.
4660         for ((i=0; i<$warmup_files; i++)); do
4661                 idx=$($LFS getstripe -i $TDIR/w$i)
4662                 [ $idx -ne 0 ] && continue
4663                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4664                 break
4665         done
4666         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4667         sync
4668         $LCTL get_param $proc_osc0/cur_dirty_bytes
4669         $LCTL get_param $proc_osc0/cur_grant_bytes
4670
4671         # create as much dirty pages as we can while not to trigger the actual
4672         # RPCs directly. but depends on the env, VFS may trigger flush during this
4673         # period, hopefully we are good.
4674         for ((i=0; i<$warmup_files; i++)); do
4675                 idx=$($LFS getstripe -i $TDIR/w$i)
4676                 [ $idx -ne 0 ] && continue
4677                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4678         done
4679         $LCTL get_param $proc_osc0/cur_dirty_bytes
4680         $LCTL get_param $proc_osc0/cur_grant_bytes
4681
4682         # perform the real test
4683         $LCTL set_param $proc_osc0/rpc_stats 0
4684         for ((;i<$files; i++)); do
4685                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4686                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4687         done
4688         sync
4689         $LCTL get_param $proc_osc0/rpc_stats
4690
4691         local percent=0
4692         local have_ppr=false
4693         $LCTL get_param $proc_osc0/rpc_stats |
4694                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4695                         # skip lines until we are at the RPC histogram data
4696                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4697                         $have_ppr || continue
4698
4699                         # we only want the percent stat for < 16 pages
4700                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4701
4702                         percent=$((percent + WPCT))
4703                         if [[ $percent -gt 15 ]]; then
4704                                 error "less than 16-pages write RPCs" \
4705                                       "$percent% > 15%"
4706                                 break
4707                         fi
4708                 done
4709         rm -rf $TDIR
4710 }
4711 run_test 42e "verify sub-RPC writes are not done synchronously"
4712
4713 test_43A() { # was test_43
4714         test_mkdir $DIR/$tdir
4715         cp -p /bin/ls $DIR/$tdir/$tfile
4716         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4717         pid=$!
4718         # give multiop a chance to open
4719         sleep 1
4720
4721         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4722         kill -USR1 $pid
4723 }
4724 run_test 43A "execution of file opened for write should return -ETXTBSY"
4725
4726 test_43a() {
4727         test_mkdir $DIR/$tdir
4728         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4729         $DIR/$tdir/sleep 60 &
4730         SLEEP_PID=$!
4731         # Make sure exec of $tdir/sleep wins race with truncate
4732         sleep 1
4733         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4734         kill $SLEEP_PID
4735 }
4736 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4737
4738 test_43b() {
4739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4740
4741         test_mkdir $DIR/$tdir
4742         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4743         $DIR/$tdir/sleep 60 &
4744         SLEEP_PID=$!
4745         # Make sure exec of $tdir/sleep wins race with truncate
4746         sleep 1
4747         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4748         kill $SLEEP_PID
4749 }
4750 run_test 43b "truncate of file being executed should return -ETXTBSY"
4751
4752 test_43c() {
4753         local testdir="$DIR/$tdir"
4754         test_mkdir $testdir
4755         cp $SHELL $testdir/
4756         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4757                 ( cd $testdir && md5sum -c )
4758 }
4759 run_test 43c "md5sum of copy into lustre"
4760
4761 test_44A() { # was test_44
4762         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4763
4764         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4765         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4766 }
4767 run_test 44A "zero length read from a sparse stripe"
4768
4769 test_44a() {
4770         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4771                 awk '{ print $2 }')
4772         [ -z "$nstripe" ] && skip "can't get stripe info"
4773         [[ $nstripe -gt $OSTCOUNT ]] &&
4774                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4775
4776         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4777                 awk '{ print $2 }')
4778         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4779                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4780                         awk '{ print $2 }')
4781         fi
4782
4783         OFFSETS="0 $((stride/2)) $((stride-1))"
4784         for offset in $OFFSETS; do
4785                 for i in $(seq 0 $((nstripe-1))); do
4786                         local GLOBALOFFSETS=""
4787                         # size in Bytes
4788                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4789                         local myfn=$DIR/d44a-$size
4790                         echo "--------writing $myfn at $size"
4791                         ll_sparseness_write $myfn $size ||
4792                                 error "ll_sparseness_write"
4793                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4794                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4795                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4796
4797                         for j in $(seq 0 $((nstripe-1))); do
4798                                 # size in Bytes
4799                                 size=$((((j + $nstripe )*$stride + $offset)))
4800                                 ll_sparseness_write $myfn $size ||
4801                                         error "ll_sparseness_write"
4802                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4803                         done
4804                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4805                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4806                         rm -f $myfn
4807                 done
4808         done
4809 }
4810 run_test 44a "test sparse pwrite ==============================="
4811
4812 dirty_osc_total() {
4813         tot=0
4814         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4815                 tot=$(($tot + $d))
4816         done
4817         echo $tot
4818 }
4819 do_dirty_record() {
4820         before=`dirty_osc_total`
4821         echo executing "\"$*\""
4822         eval $*
4823         after=`dirty_osc_total`
4824         echo before $before, after $after
4825 }
4826 test_45() {
4827         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4828
4829         f="$DIR/f45"
4830         # Obtain grants from OST if it supports it
4831         echo blah > ${f}_grant
4832         stop_writeback
4833         sync
4834         do_dirty_record "echo blah > $f"
4835         [[ $before -eq $after ]] && error "write wasn't cached"
4836         do_dirty_record "> $f"
4837         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4838         do_dirty_record "echo blah > $f"
4839         [[ $before -eq $after ]] && error "write wasn't cached"
4840         do_dirty_record "sync"
4841         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4842         do_dirty_record "echo blah > $f"
4843         [[ $before -eq $after ]] && error "write wasn't cached"
4844         do_dirty_record "cancel_lru_locks osc"
4845         [[ $before -gt $after ]] ||
4846                 error "lock cancellation didn't lower dirty count"
4847         start_writeback
4848 }
4849 run_test 45 "osc io page accounting ============================"
4850
4851 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4852 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4853 # objects offset and an assert hit when an rpc was built with 1023's mapped
4854 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4855 test_46() {
4856         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4857
4858         f="$DIR/f46"
4859         stop_writeback
4860         sync
4861         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4862         sync
4863         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4864         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4865         sync
4866         start_writeback
4867 }
4868 run_test 46 "dirtying a previously written page ================"
4869
4870 # test_47 is removed "Device nodes check" is moved to test_28
4871
4872 test_48a() { # bug 2399
4873         [ "$mds1_FSTYPE" = "zfs" ] &&
4874         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4875                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4876
4877         test_mkdir $DIR/$tdir
4878         cd $DIR/$tdir
4879         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4880         test_mkdir $DIR/$tdir
4881         touch foo || error "'touch foo' failed after recreating cwd"
4882         test_mkdir bar
4883         touch .foo || error "'touch .foo' failed after recreating cwd"
4884         test_mkdir .bar
4885         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4886         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4887         cd . || error "'cd .' failed after recreating cwd"
4888         mkdir . && error "'mkdir .' worked after recreating cwd"
4889         rmdir . && error "'rmdir .' worked after recreating cwd"
4890         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4891         cd .. || error "'cd ..' failed after recreating cwd"
4892 }
4893 run_test 48a "Access renamed working dir (should return errors)="
4894
4895 test_48b() { # bug 2399
4896         rm -rf $DIR/$tdir
4897         test_mkdir $DIR/$tdir
4898         cd $DIR/$tdir
4899         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4900         touch foo && error "'touch foo' worked after removing cwd"
4901         mkdir foo && error "'mkdir foo' worked after removing cwd"
4902         touch .foo && error "'touch .foo' worked after removing cwd"
4903         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4904         ls . > /dev/null && error "'ls .' worked after removing cwd"
4905         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4906         mkdir . && error "'mkdir .' worked after removing cwd"
4907         rmdir . && error "'rmdir .' worked after removing cwd"
4908         ln -s . foo && error "'ln -s .' worked after removing cwd"
4909         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4910 }
4911 run_test 48b "Access removed working dir (should return errors)="
4912
4913 test_48c() { # bug 2350
4914         #lctl set_param debug=-1
4915         #set -vx
4916         rm -rf $DIR/$tdir
4917         test_mkdir -p $DIR/$tdir/dir
4918         cd $DIR/$tdir/dir
4919         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4920         $TRACE touch foo && error "touch foo worked after removing cwd"
4921         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4922         touch .foo && error "touch .foo worked after removing cwd"
4923         mkdir .foo && error "mkdir .foo worked after removing cwd"
4924         $TRACE ls . && error "'ls .' worked after removing cwd"
4925         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4926         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4927         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4928         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4929         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4930 }
4931 run_test 48c "Access removed working subdir (should return errors)"
4932
4933 test_48d() { # bug 2350
4934         #lctl set_param debug=-1
4935         #set -vx
4936         rm -rf $DIR/$tdir
4937         test_mkdir -p $DIR/$tdir/dir
4938         cd $DIR/$tdir/dir
4939         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4940         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4941         $TRACE touch foo && error "'touch foo' worked after removing parent"
4942         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4943         touch .foo && error "'touch .foo' worked after removing parent"
4944         mkdir .foo && error "mkdir .foo worked after removing parent"
4945         $TRACE ls . && error "'ls .' worked after removing parent"
4946         $TRACE ls .. && error "'ls ..' worked after removing parent"
4947         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4948         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4949         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4950         true
4951 }
4952 run_test 48d "Access removed parent subdir (should return errors)"
4953
4954 test_48e() { # bug 4134
4955         #lctl set_param debug=-1
4956         #set -vx
4957         rm -rf $DIR/$tdir
4958         test_mkdir -p $DIR/$tdir/dir
4959         cd $DIR/$tdir/dir
4960         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4961         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4962         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4963         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4964         # On a buggy kernel addition of "touch foo" after cd .. will
4965         # produce kernel oops in lookup_hash_it
4966         touch ../foo && error "'cd ..' worked after recreate parent"
4967         cd $DIR
4968         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4969 }
4970 run_test 48e "Access to recreated parent subdir (should return errors)"
4971
4972 test_49() { # LU-1030
4973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4974         remote_ost_nodsh && skip "remote OST with nodsh"
4975
4976         # get ost1 size - lustre-OST0000
4977         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4978                 awk '{ print $4 }')
4979         # write 800M at maximum
4980         [[ $ost1_size -lt 2 ]] && ost1_size=2
4981         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4982
4983         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4984         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4985         local dd_pid=$!
4986
4987         # change max_pages_per_rpc while writing the file
4988         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4989         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4990         # loop until dd process exits
4991         while ps ax -opid | grep -wq $dd_pid; do
4992                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4993                 sleep $((RANDOM % 5 + 1))
4994         done
4995         # restore original max_pages_per_rpc
4996         $LCTL set_param $osc1_mppc=$orig_mppc
4997         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4998 }
4999 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5000
5001 test_50() {
5002         # bug 1485
5003         test_mkdir $DIR/$tdir
5004         cd $DIR/$tdir
5005         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5006 }
5007 run_test 50 "special situations: /proc symlinks  ==============="
5008
5009 test_51a() {    # was test_51
5010         # bug 1516 - create an empty entry right after ".." then split dir
5011         test_mkdir -c1 $DIR/$tdir
5012         touch $DIR/$tdir/foo
5013         $MCREATE $DIR/$tdir/bar
5014         rm $DIR/$tdir/foo
5015         createmany -m $DIR/$tdir/longfile 201
5016         FNUM=202
5017         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5018                 $MCREATE $DIR/$tdir/longfile$FNUM
5019                 FNUM=$(($FNUM + 1))
5020                 echo -n "+"
5021         done
5022         echo
5023         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5024 }
5025 run_test 51a "special situations: split htree with empty entry =="
5026
5027 cleanup_print_lfs_df () {
5028         trap 0
5029         $LFS df
5030         $LFS df -i
5031 }
5032
5033 test_51b() {
5034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5035
5036         local dir=$DIR/$tdir
5037         local nrdirs=$((65536 + 100))
5038
5039         # cleanup the directory
5040         rm -fr $dir
5041
5042         test_mkdir -c1 $dir
5043
5044         $LFS df
5045         $LFS df -i
5046         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5047         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5048         [[ $numfree -lt $nrdirs ]] &&
5049                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5050
5051         # need to check free space for the directories as well
5052         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5053         numfree=$(( blkfree / $(fs_inode_ksize) ))
5054         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5055
5056         trap cleanup_print_lfs_df EXIT
5057
5058         # create files
5059         createmany -d $dir/d $nrdirs || {
5060                 unlinkmany $dir/d $nrdirs
5061                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5062         }
5063
5064         # really created :
5065         nrdirs=$(ls -U $dir | wc -l)
5066
5067         # unlink all but 100 subdirectories, then check it still works
5068         local left=100
5069         local delete=$((nrdirs - left))
5070
5071         $LFS df
5072         $LFS df -i
5073
5074         # for ldiskfs the nlink count should be 1, but this is OSD specific
5075         # and so this is listed for informational purposes only
5076         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5077         unlinkmany -d $dir/d $delete ||
5078                 error "unlink of first $delete subdirs failed"
5079
5080         echo "nlink between: $(stat -c %h $dir)"
5081         local found=$(ls -U $dir | wc -l)
5082         [ $found -ne $left ] &&
5083                 error "can't find subdirs: found only $found, expected $left"
5084
5085         unlinkmany -d $dir/d $delete $left ||
5086                 error "unlink of second $left subdirs failed"
5087         # regardless of whether the backing filesystem tracks nlink accurately
5088         # or not, the nlink count shouldn't be more than "." and ".." here
5089         local after=$(stat -c %h $dir)
5090         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5091                 echo "nlink after: $after"
5092
5093         cleanup_print_lfs_df
5094 }
5095 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5096
5097 test_51d() {
5098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5099         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5100
5101         test_mkdir $DIR/$tdir
5102         createmany -o $DIR/$tdir/t- 1000
5103         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5104         for N in $(seq 0 $((OSTCOUNT - 1))); do
5105                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5106                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5107                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5108                         '($1 == '$N') { objs += 1 } \
5109                         END { printf("%0.0f", objs) }')
5110                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5111         done
5112         unlinkmany $DIR/$tdir/t- 1000
5113
5114         NLAST=0
5115         for N in $(seq 1 $((OSTCOUNT - 1))); do
5116                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5117                         error "OST $N has less objects vs OST $NLAST" \
5118                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5119                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5120                         error "OST $N has less objects vs OST $NLAST" \
5121                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5122
5123                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5124                         error "OST $N has less #0 objects vs OST $NLAST" \
5125                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5126                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5127                         error "OST $N has less #0 objects vs OST $NLAST" \
5128                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5129                 NLAST=$N
5130         done
5131         rm -f $TMP/$tfile
5132 }
5133 run_test 51d "check object distribution"
5134
5135 test_51e() {
5136         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5137                 skip_env "ldiskfs only test"
5138         fi
5139
5140         test_mkdir -c1 $DIR/$tdir
5141         test_mkdir -c1 $DIR/$tdir/d0
5142
5143         touch $DIR/$tdir/d0/foo
5144         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5145                 error "file exceed 65000 nlink limit!"
5146         unlinkmany $DIR/$tdir/d0/f- 65001
5147         return 0
5148 }
5149 run_test 51e "check file nlink limit"
5150
5151 test_51f() {
5152         test_mkdir $DIR/$tdir
5153
5154         local max=100000
5155         local ulimit_old=$(ulimit -n)
5156         local spare=20 # number of spare fd's for scripts/libraries, etc.
5157         local mdt=$($LFS getstripe -m $DIR/$tdir)
5158         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5159
5160         echo "MDT$mdt numfree=$numfree, max=$max"
5161         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5162         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5163                 while ! ulimit -n $((numfree + spare)); do
5164                         numfree=$((numfree * 3 / 4))
5165                 done
5166                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5167         else
5168                 echo "left ulimit at $ulimit_old"
5169         fi
5170
5171         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5172                 unlinkmany $DIR/$tdir/f $numfree
5173                 error "create+open $numfree files in $DIR/$tdir failed"
5174         }
5175         ulimit -n $ulimit_old
5176
5177         # if createmany exits at 120s there will be fewer than $numfree files
5178         unlinkmany $DIR/$tdir/f $numfree || true
5179 }
5180 run_test 51f "check many open files limit"
5181
5182 test_52a() {
5183         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5184         test_mkdir $DIR/$tdir
5185         touch $DIR/$tdir/foo
5186         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5187         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5188         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5189         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5190         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5191                                         error "link worked"
5192         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5193         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5194         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5195                                                      error "lsattr"
5196         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5197         cp -r $DIR/$tdir $TMP/
5198         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5199 }
5200 run_test 52a "append-only flag test (should return errors)"
5201
5202 test_52b() {
5203         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5204         test_mkdir $DIR/$tdir
5205         touch $DIR/$tdir/foo
5206         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5207         cat test > $DIR/$tdir/foo && error "cat test worked"
5208         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5209         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5210         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5211                                         error "link worked"
5212         echo foo >> $DIR/$tdir/foo && error "echo worked"
5213         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5214         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5215         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5216         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5217                                                         error "lsattr"
5218         chattr -i $DIR/$tdir/foo || error "chattr failed"
5219
5220         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5221 }
5222 run_test 52b "immutable flag test (should return errors) ======="
5223
5224 test_53() {
5225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5226         remote_mds_nodsh && skip "remote MDS with nodsh"
5227         remote_ost_nodsh && skip "remote OST with nodsh"
5228
5229         local param
5230         local param_seq
5231         local ostname
5232         local mds_last
5233         local mds_last_seq
5234         local ost_last
5235         local ost_last_seq
5236         local ost_last_id
5237         local ostnum
5238         local node
5239         local found=false
5240         local support_last_seq=true
5241
5242         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5243                 support_last_seq=false
5244
5245         # only test MDT0000
5246         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5247         local value
5248         for value in $(do_facet $SINGLEMDS \
5249                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5250                 param=$(echo ${value[0]} | cut -d "=" -f1)
5251                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5252
5253                 if $support_last_seq; then
5254                         param_seq=$(echo $param |
5255                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5256                         mds_last_seq=$(do_facet $SINGLEMDS \
5257                                        $LCTL get_param -n $param_seq)
5258                 fi
5259                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5260
5261                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5262                 node=$(facet_active_host ost$((ostnum+1)))
5263                 param="obdfilter.$ostname.last_id"
5264                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5265                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5266                         ost_last_id=$ost_last
5267
5268                         if $support_last_seq; then
5269                                 ost_last_id=$(echo $ost_last |
5270                                               awk -F':' '{print $2}' |
5271                                               sed -e "s/^0x//g")
5272                                 ost_last_seq=$(echo $ost_last |
5273                                                awk -F':' '{print $1}')
5274                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5275                         fi
5276
5277                         if [[ $ost_last_id != $mds_last ]]; then
5278                                 error "$ost_last_id != $mds_last"
5279                         else
5280                                 found=true
5281                                 break
5282                         fi
5283                 done
5284         done
5285         $found || error "can not match last_seq/last_id for $mdtosc"
5286         return 0
5287 }
5288 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5289
5290 test_54a() {
5291         perl -MSocket -e ';' || skip "no Socket perl module installed"
5292
5293         $SOCKETSERVER $DIR/socket ||
5294                 error "$SOCKETSERVER $DIR/socket failed: $?"
5295         $SOCKETCLIENT $DIR/socket ||
5296                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5297         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5298 }
5299 run_test 54a "unix domain socket test =========================="
5300
5301 test_54b() {
5302         f="$DIR/f54b"
5303         mknod $f c 1 3
5304         chmod 0666 $f
5305         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5306 }
5307 run_test 54b "char device works in lustre ======================"
5308
5309 find_loop_dev() {
5310         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5311         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5312         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5313
5314         for i in $(seq 3 7); do
5315                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5316                 LOOPDEV=$LOOPBASE$i
5317                 LOOPNUM=$i
5318                 break
5319         done
5320 }
5321
5322 cleanup_54c() {
5323         local rc=0
5324         loopdev="$DIR/loop54c"
5325
5326         trap 0
5327         $UMOUNT $DIR/$tdir || rc=$?
5328         losetup -d $loopdev || true
5329         losetup -d $LOOPDEV || true
5330         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5331         return $rc
5332 }
5333
5334 test_54c() {
5335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5336
5337         loopdev="$DIR/loop54c"
5338
5339         find_loop_dev
5340         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5341         trap cleanup_54c EXIT
5342         mknod $loopdev b 7 $LOOPNUM
5343         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5344         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5345         losetup $loopdev $DIR/$tfile ||
5346                 error "can't set up $loopdev for $DIR/$tfile"
5347         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5348         test_mkdir $DIR/$tdir
5349         mount -t ext2 $loopdev $DIR/$tdir ||
5350                 error "error mounting $loopdev on $DIR/$tdir"
5351         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5352                 error "dd write"
5353         df $DIR/$tdir
5354         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5355                 error "dd read"
5356         cleanup_54c
5357 }
5358 run_test 54c "block device works in lustre ====================="
5359
5360 test_54d() {
5361         f="$DIR/f54d"
5362         string="aaaaaa"
5363         mknod $f p
5364         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5365 }
5366 run_test 54d "fifo device works in lustre ======================"
5367
5368 test_54e() {
5369         f="$DIR/f54e"
5370         string="aaaaaa"
5371         cp -aL /dev/console $f
5372         echo $string > $f || error "echo $string to $f failed"
5373 }
5374 run_test 54e "console/tty device works in lustre ======================"
5375
5376 test_56a() {
5377         local numfiles=3
5378         local dir=$DIR/$tdir
5379
5380         rm -rf $dir
5381         test_mkdir -p $dir/dir
5382         for i in $(seq $numfiles); do
5383                 touch $dir/file$i
5384                 touch $dir/dir/file$i
5385         done
5386
5387         local numcomp=$($LFS getstripe --component-count $dir)
5388
5389         [[ $numcomp == 0 ]] && numcomp=1
5390
5391         # test lfs getstripe with --recursive
5392         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5393
5394         [[ $filenum -eq $((numfiles * 2)) ]] ||
5395                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5396         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5397         [[ $filenum -eq $numfiles ]] ||
5398                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5399         echo "$LFS getstripe showed obdidx or l_ost_idx"
5400
5401         # test lfs getstripe with file instead of dir
5402         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5403         [[ $filenum -eq 1 ]] ||
5404                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5405         echo "$LFS getstripe file1 passed"
5406
5407         #test lfs getstripe with --verbose
5408         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5409         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5410                 error "$LFS getstripe --verbose $dir: "\
5411                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5412         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5413                 error "$LFS getstripe $dir: showed lmm_magic"
5414
5415         #test lfs getstripe with -v prints lmm_fid
5416         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5417         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5418                 error "$LFS getstripe -v $dir: "\
5419                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5420         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5421                 error "$LFS getstripe $dir: showed lmm_fid by default"
5422         echo "$LFS getstripe --verbose passed"
5423
5424         #check for FID information
5425         local fid1=$($LFS getstripe --fid $dir/file1)
5426         local fid2=$($LFS getstripe --verbose $dir/file1 |
5427                      awk '/lmm_fid: / { print $2; exit; }')
5428         local fid3=$($LFS path2fid $dir/file1)
5429
5430         [ "$fid1" != "$fid2" ] &&
5431                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5432         [ "$fid1" != "$fid3" ] &&
5433                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5434         echo "$LFS getstripe --fid passed"
5435
5436         #test lfs getstripe with --obd
5437         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5438                 error "$LFS getstripe --obd wrong_uuid: should return error"
5439
5440         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5441
5442         local ostidx=1
5443         local obduuid=$(ostuuid_from_index $ostidx)
5444         local found=$($LFS getstripe -r --obd $obduuid $dir |
5445                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5446
5447         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5448         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5449                 ((filenum--))
5450         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5451                 ((filenum--))
5452
5453         [[ $found -eq $filenum ]] ||
5454                 error "$LFS getstripe --obd: found $found expect $filenum"
5455         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5456                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5457                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5458                 error "$LFS getstripe --obd: should not show file on other obd"
5459         echo "$LFS getstripe --obd passed"
5460 }
5461 run_test 56a "check $LFS getstripe"
5462
5463 test_56b() {
5464         local dir=$DIR/$tdir
5465         local numdirs=3
5466
5467         test_mkdir $dir
5468         for i in $(seq $numdirs); do
5469                 test_mkdir $dir/dir$i
5470         done
5471
5472         # test lfs getdirstripe default mode is non-recursion, which is
5473         # different from lfs getstripe
5474         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5475
5476         [[ $dircnt -eq 1 ]] ||
5477                 error "$LFS getdirstripe: found $dircnt, not 1"
5478         dircnt=$($LFS getdirstripe --recursive $dir |
5479                 grep -c lmv_stripe_count)
5480         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5481                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5482 }
5483 run_test 56b "check $LFS getdirstripe"
5484
5485 test_56c() {
5486         remote_ost_nodsh && skip "remote OST with nodsh"
5487
5488         local ost_idx=0
5489         local ost_name=$(ostname_from_index $ost_idx)
5490         local old_status=$(ost_dev_status $ost_idx)
5491
5492         [[ -z "$old_status" ]] ||
5493                 skip_env "OST $ost_name is in $old_status status"
5494
5495         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5496         sleep_maxage
5497
5498         local new_status=$(ost_dev_status $ost_idx)
5499
5500         [[ "$new_status" = "D" ]] ||
5501                 error "OST $ost_name is in status of '$new_status', not 'D'"
5502
5503         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5504         sleep_maxage
5505
5506         new_status=$(ost_dev_status $ost_idx)
5507         [[ -z "$new_status" ]] ||
5508                 error "OST $ost_name is in status of '$new_status', not ''"
5509 }
5510 run_test 56c "check 'lfs df' showing device status"
5511
5512 NUMFILES=3
5513 NUMDIRS=3
5514 setup_56() {
5515         local local_tdir="$1"
5516         local local_numfiles="$2"
5517         local local_numdirs="$3"
5518         local dir_params="$4"
5519         local dir_stripe_params="$5"
5520
5521         if [ ! -d "$local_tdir" ] ; then
5522                 test_mkdir -p $dir_stripe_params $local_tdir
5523                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5524                 for i in $(seq $local_numfiles) ; do
5525                         touch $local_tdir/file$i
5526                 done
5527                 for i in $(seq $local_numdirs) ; do
5528                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5529                         for j in $(seq $local_numfiles) ; do
5530                                 touch $local_tdir/dir$i/file$j
5531                         done
5532                 done
5533         fi
5534 }
5535
5536 setup_56_special() {
5537         local local_tdir=$1
5538         local local_numfiles=$2
5539         local local_numdirs=$3
5540
5541         setup_56 $local_tdir $local_numfiles $local_numdirs
5542
5543         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5544                 for i in $(seq $local_numfiles) ; do
5545                         mknod $local_tdir/loop${i}b b 7 $i
5546                         mknod $local_tdir/null${i}c c 1 3
5547                         ln -s $local_tdir/file1 $local_tdir/link${i}
5548                 done
5549                 for i in $(seq $local_numdirs) ; do
5550                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5551                         mknod $local_tdir/dir$i/null${i}c c 1 3
5552                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5553                 done
5554         fi
5555 }
5556
5557 test_56g() {
5558         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5559         local expected=$(($NUMDIRS + 2))
5560
5561         setup_56 $dir $NUMFILES $NUMDIRS
5562
5563         # test lfs find with -name
5564         for i in $(seq $NUMFILES) ; do
5565                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5566
5567                 [ $nums -eq $expected ] ||
5568                         error "lfs find -name '*$i' $dir wrong: "\
5569                               "found $nums, expected $expected"
5570         done
5571 }
5572 run_test 56g "check lfs find -name"
5573
5574 test_56h() {
5575         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5576         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5577
5578         setup_56 $dir $NUMFILES $NUMDIRS
5579
5580         # test lfs find with ! -name
5581         for i in $(seq $NUMFILES) ; do
5582                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5583
5584                 [ $nums -eq $expected ] ||
5585                         error "lfs find ! -name '*$i' $dir wrong: "\
5586                               "found $nums, expected $expected"
5587         done
5588 }
5589 run_test 56h "check lfs find ! -name"
5590
5591 test_56i() {
5592         local dir=$DIR/$tdir
5593
5594         test_mkdir $dir
5595
5596         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5597         local out=$($cmd)
5598
5599         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5600 }
5601 run_test 56i "check 'lfs find -ost UUID' skips directories"
5602
5603 test_56j() {
5604         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5605
5606         setup_56_special $dir $NUMFILES $NUMDIRS
5607
5608         local expected=$((NUMDIRS + 1))
5609         local cmd="$LFS find -type d $dir"
5610         local nums=$($cmd | wc -l)
5611
5612         [ $nums -eq $expected ] ||
5613                 error "'$cmd' wrong: found $nums, expected $expected"
5614 }
5615 run_test 56j "check lfs find -type d"
5616
5617 test_56k() {
5618         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5619
5620         setup_56_special $dir $NUMFILES $NUMDIRS
5621
5622         local expected=$(((NUMDIRS + 1) * NUMFILES))
5623         local cmd="$LFS find -type f $dir"
5624         local nums=$($cmd | wc -l)
5625
5626         [ $nums -eq $expected ] ||
5627                 error "'$cmd' wrong: found $nums, expected $expected"
5628 }
5629 run_test 56k "check lfs find -type f"
5630
5631 test_56l() {
5632         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5633
5634         setup_56_special $dir $NUMFILES $NUMDIRS
5635
5636         local expected=$((NUMDIRS + NUMFILES))
5637         local cmd="$LFS find -type b $dir"
5638         local nums=$($cmd | wc -l)
5639
5640         [ $nums -eq $expected ] ||
5641                 error "'$cmd' wrong: found $nums, expected $expected"
5642 }
5643 run_test 56l "check lfs find -type b"
5644
5645 test_56m() {
5646         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5647
5648         setup_56_special $dir $NUMFILES $NUMDIRS
5649
5650         local expected=$((NUMDIRS + NUMFILES))
5651         local cmd="$LFS find -type c $dir"
5652         local nums=$($cmd | wc -l)
5653         [ $nums -eq $expected ] ||
5654                 error "'$cmd' wrong: found $nums, expected $expected"
5655 }
5656 run_test 56m "check lfs find -type c"
5657
5658 test_56n() {
5659         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5660         setup_56_special $dir $NUMFILES $NUMDIRS
5661
5662         local expected=$((NUMDIRS + NUMFILES))
5663         local cmd="$LFS find -type l $dir"
5664         local nums=$($cmd | wc -l)
5665
5666         [ $nums -eq $expected ] ||
5667                 error "'$cmd' wrong: found $nums, expected $expected"
5668 }
5669 run_test 56n "check lfs find -type l"
5670
5671 test_56o() {
5672         local dir=$DIR/$tdir
5673
5674         setup_56 $dir $NUMFILES $NUMDIRS
5675         utime $dir/file1 > /dev/null || error "utime (1)"
5676         utime $dir/file2 > /dev/null || error "utime (2)"
5677         utime $dir/dir1 > /dev/null || error "utime (3)"
5678         utime $dir/dir2 > /dev/null || error "utime (4)"
5679         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5680         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5681
5682         local expected=4
5683         local nums=$($LFS find -mtime +0 $dir | wc -l)
5684
5685         [ $nums -eq $expected ] ||
5686                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5687
5688         expected=12
5689         cmd="$LFS find -mtime 0 $dir"
5690         nums=$($cmd | wc -l)
5691         [ $nums -eq $expected ] ||
5692                 error "'$cmd' wrong: found $nums, expected $expected"
5693 }
5694 run_test 56o "check lfs find -mtime for old files"
5695
5696 test_56ob() {
5697         local dir=$DIR/$tdir
5698         local expected=1
5699         local count=0
5700
5701         # just to make sure there is something that won't be found
5702         test_mkdir $dir
5703         touch $dir/$tfile.now
5704
5705         for age in year week day hour min; do
5706                 count=$((count + 1))
5707
5708                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5709                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5710                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5711
5712                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5713                 local nums=$($cmd | wc -l)
5714                 [ $nums -eq $expected ] ||
5715                         error "'$cmd' wrong: found $nums, expected $expected"
5716
5717                 cmd="$LFS find $dir -atime $count${age:0:1}"
5718                 nums=$($cmd | wc -l)
5719                 [ $nums -eq $expected ] ||
5720                         error "'$cmd' wrong: found $nums, expected $expected"
5721         done
5722
5723         sleep 2
5724         cmd="$LFS find $dir -ctime +1s -type f"
5725         nums=$($cmd | wc -l)
5726         (( $nums == $count * 2 + 1)) ||
5727                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5728 }
5729 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5730
5731 test_56p() {
5732         [ $RUNAS_ID -eq $UID ] &&
5733                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5734
5735         local dir=$DIR/$tdir
5736
5737         setup_56 $dir $NUMFILES $NUMDIRS
5738         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5739
5740         local expected=$NUMFILES
5741         local cmd="$LFS find -uid $RUNAS_ID $dir"
5742         local nums=$($cmd | wc -l)
5743
5744         [ $nums -eq $expected ] ||
5745                 error "'$cmd' wrong: found $nums, expected $expected"
5746
5747         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5748         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5749         nums=$($cmd | wc -l)
5750         [ $nums -eq $expected ] ||
5751                 error "'$cmd' wrong: found $nums, expected $expected"
5752 }
5753 run_test 56p "check lfs find -uid and ! -uid"
5754
5755 test_56q() {
5756         [ $RUNAS_ID -eq $UID ] &&
5757                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5758
5759         local dir=$DIR/$tdir
5760
5761         setup_56 $dir $NUMFILES $NUMDIRS
5762         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5763
5764         local expected=$NUMFILES
5765         local cmd="$LFS find -gid $RUNAS_GID $dir"
5766         local nums=$($cmd | wc -l)
5767
5768         [ $nums -eq $expected ] ||
5769                 error "'$cmd' wrong: found $nums, expected $expected"
5770
5771         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5772         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5773         nums=$($cmd | wc -l)
5774         [ $nums -eq $expected ] ||
5775                 error "'$cmd' wrong: found $nums, expected $expected"
5776 }
5777 run_test 56q "check lfs find -gid and ! -gid"
5778
5779 test_56r() {
5780         local dir=$DIR/$tdir
5781
5782         setup_56 $dir $NUMFILES $NUMDIRS
5783
5784         local expected=12
5785         local cmd="$LFS find -size 0 -type f -lazy $dir"
5786         local nums=$($cmd | wc -l)
5787
5788         [ $nums -eq $expected ] ||
5789                 error "'$cmd' wrong: found $nums, expected $expected"
5790         cmd="$LFS find -size 0 -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         expected=0
5796         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5797         nums=$($cmd | wc -l)
5798         [ $nums -eq $expected ] ||
5799                 error "'$cmd' wrong: found $nums, expected $expected"
5800         cmd="$LFS find ! -size 0 -type f $dir"
5801         nums=$($cmd | wc -l)
5802         [ $nums -eq $expected ] ||
5803                 error "'$cmd' wrong: found $nums, expected $expected"
5804
5805         echo "test" > $dir/$tfile
5806         echo "test2" > $dir/$tfile.2 && sync
5807         expected=1
5808         cmd="$LFS find -size 5 -type f -lazy $dir"
5809         nums=$($cmd | wc -l)
5810         [ $nums -eq $expected ] ||
5811                 error "'$cmd' wrong: found $nums, expected $expected"
5812         cmd="$LFS find -size 5 -type f $dir"
5813         nums=$($cmd | wc -l)
5814         [ $nums -eq $expected ] ||
5815                 error "'$cmd' wrong: found $nums, expected $expected"
5816
5817         expected=1
5818         cmd="$LFS find -size +5 -type f -lazy $dir"
5819         nums=$($cmd | wc -l)
5820         [ $nums -eq $expected ] ||
5821                 error "'$cmd' wrong: found $nums, expected $expected"
5822         cmd="$LFS find -size +5 -type f $dir"
5823         nums=$($cmd | wc -l)
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=2
5828         cmd="$LFS find -size +0 -type f -lazy $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832         cmd="$LFS find -size +0 -type f $dir"
5833         nums=$($cmd | wc -l)
5834         [ $nums -eq $expected ] ||
5835                 error "'$cmd' wrong: found $nums, expected $expected"
5836
5837         expected=2
5838         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5839         nums=$($cmd | wc -l)
5840         [ $nums -eq $expected ] ||
5841                 error "'$cmd' wrong: found $nums, expected $expected"
5842         cmd="$LFS find ! -size -5 -type f $dir"
5843         nums=$($cmd | wc -l)
5844         [ $nums -eq $expected ] ||
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846
5847         expected=12
5848         cmd="$LFS find -size -5 -type f -lazy $dir"
5849         nums=$($cmd | wc -l)
5850         [ $nums -eq $expected ] ||
5851                 error "'$cmd' wrong: found $nums, expected $expected"
5852         cmd="$LFS find -size -5 -type f $dir"
5853         nums=$($cmd | wc -l)
5854         [ $nums -eq $expected ] ||
5855                 error "'$cmd' wrong: found $nums, expected $expected"
5856 }
5857 run_test 56r "check lfs find -size works"
5858
5859 test_56ra() {
5860         local dir=$DIR/$tdir
5861
5862         [[ $OSC == "mdc" ]] && skip "DoM files" && return
5863
5864         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5865
5866         cancel_lru_locks $OSC
5867
5868         local rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5869         local expected=12
5870         local cmd="$LFS find -size 0 -type f -lazy $dir"
5871         local nums=$($cmd | wc -l)
5872
5873         [ $nums -eq $expected ] ||
5874                 error "'$cmd' wrong: found $nums, expected $expected"
5875
5876         local rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5877         [ $rpcs_before -eq $rpcs_after ] ||
5878                 error "'$cmd' should not send glimpse RPCs to OST"
5879         cmd="$LFS find -size 0 -type f $dir"
5880         nums=$($cmd | wc -l)
5881         [ $nums -eq $expected ] ||
5882                 error "'$cmd' wrong: found $nums, expected $expected"
5883         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5884         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5885         $LCTL get_param osc.*.stats
5886         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5887                 error "'$cmd' should send 12 glimpse RPCs to OST"
5888
5889         cancel_lru_locks $OSC
5890         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5891         expected=0
5892         cmd="$LFS find ! -size 0 -type f -lazy $dir"
5893         nums=$($cmd | wc -l)
5894         [ $nums -eq $expected ] ||
5895                 error "'$cmd' wrong: found $nums, expected $expected"
5896         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5897         $LCTL get_param mdc.*.stats
5898         [ $rpcs_before -eq $rpcs_after ] ||
5899                 error "'$cmd' should not send glimpse RPCs to OST"
5900         cmd="$LFS find ! -size 0 -type f $dir"
5901         nums=$($cmd | wc -l)
5902         [ $nums -eq $expected ] ||
5903                 error "'$cmd' wrong: found $nums, expected $expected"
5904         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5905         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5906         [ $rpcs_after -eq $((rpcs_before + 12)) ] ||
5907                 error "'$cmd' should send 12 glimpse RPCs to OST"
5908
5909         echo "test" > $dir/$tfile
5910         echo "test2" > $dir/$tfile.2 && sync
5911         cancel_lru_locks $OSC
5912         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5913         expected=1
5914         cmd="$LFS find -size 5 -type f -lazy $dir"
5915         nums=$($cmd | wc -l)
5916         [ $nums -eq $expected ] ||
5917                 error "'$cmd' wrong: found $nums, expected $expected"
5918         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5919         [ $rpcs_before -eq $rpcs_after ] ||
5920                 error "'$cmd' should not send glimpse RPCs to OST"
5921         cmd="$LFS find -size 5 -type f $dir"
5922         nums=$($cmd | wc -l)
5923         [ $nums -eq $expected ] ||
5924                 error "'$cmd' wrong: found $nums, expected $expected"
5925         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5926         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5927         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5928                 error "'$cmd' should send 14 glimpse RPCs to OST"
5929
5930         cancel_lru_locks $OSC
5931         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5932         expected=1
5933         cmd="$LFS find -size +5 -type f -lazy $dir"
5934         nums=$($cmd | wc -l)
5935         [ $nums -eq $expected ] ||
5936                 error "'$cmd' wrong: found $nums, expected $expected"
5937         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5938         [ $rpcs_before -eq $rpcs_after ] ||
5939                 error "'$cmd' should not send glimpse RPCs to OST"
5940         cmd="$LFS find -size +5 -type f $dir"
5941         nums=$($cmd | wc -l)
5942         [ $nums -eq $expected ] ||
5943                 error "'$cmd' wrong: found $nums, expected $expected"
5944         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5945         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5946         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5947                 error "'$cmd' should send 14 glimpse RPCs to OST"
5948
5949         cancel_lru_locks $OSC
5950         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5951         expected=2
5952         cmd="$LFS find -size +0 -type f -lazy $dir"
5953         nums=$($cmd | wc -l)
5954         [ $nums -eq $expected ] ||
5955                 error "'$cmd' wrong: found $nums, expected $expected"
5956         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5957         [ $rpcs_before -eq $rpcs_after ] ||
5958                 error "'$cmd' should not send glimpse RPCs to OST"
5959         cmd="$LFS find -size +0 -type f $dir"
5960         nums=$($cmd | wc -l)
5961         [ $nums -eq $expected ] ||
5962                 error "'$cmd' wrong: found $nums, expected $expected"
5963         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5964         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5965         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5966                 error "'$cmd' should send 14 glimpse RPCs to OST"
5967
5968         cancel_lru_locks $OSC
5969         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5970         expected=2
5971         cmd="$LFS find ! -size -5 -type f -lazy $dir"
5972         nums=$($cmd | wc -l)
5973         [ $nums -eq $expected ] ||
5974                 error "'$cmd' wrong: found $nums, expected $expected"
5975         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5976         [ $rpcs_before -eq $rpcs_after ] ||
5977                 error "'$cmd' should not send glimpse RPCs to OST"
5978         cmd="$LFS find ! -size -5 -type f $dir"
5979         nums=$($cmd | wc -l)
5980         [ $nums -eq $expected ] ||
5981                 error "'$cmd' wrong: found $nums, expected $expected"
5982         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5983         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
5984         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
5985                 error "'$cmd' should send 14 glimpse RPCs to OST"
5986
5987         cancel_lru_locks $OSC
5988         rpcs_before=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5989         expected=12
5990         cmd="$LFS find -size -5 -type f -lazy $dir"
5991         nums=$($cmd | wc -l)
5992         [ $nums -eq $expected ] ||
5993                 error "'$cmd' wrong: found $nums, expected $expected"
5994         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
5995         [ $rpcs_before -eq $rpcs_after ] ||
5996                 error "'$cmd' should not send glimpse RPCs to OST"
5997         cmd="$LFS find -size -5 -type f $dir"
5998         nums=$($cmd | wc -l)
5999         [ $nums -eq $expected ] ||
6000                 error "'$cmd' wrong: found $nums, expected $expected"
6001         rpcs_after=$(calc_stats $OSC.*$OSC*.stats ldlm_glimpse_enqueue)
6002         echo "Before: $rpcs_before After: $rpcs_after $NUMFILES"
6003         [ $rpcs_after -eq $((rpcs_before + 14)) ] ||
6004                 error "'$cmd' should send 14 glimpse RPCs to OST"
6005 }
6006 run_test 56ra "check lfs find -size -lazy works for data on OSTs"
6007
6008 test_56s() { # LU-611 #LU-9369
6009         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
6010
6011         local dir=$DIR/$tdir
6012         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
6013
6014         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
6015         for i in $(seq $NUMDIRS); do
6016                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
6017         done
6018
6019         local expected=$NUMDIRS
6020         local cmd="$LFS find -c $OSTCOUNT $dir"
6021         local nums=$($cmd | wc -l)
6022
6023         [ $nums -eq $expected ] || {
6024                 $LFS getstripe -R $dir
6025                 error "'$cmd' wrong: found $nums, expected $expected"
6026         }
6027
6028         expected=$((NUMDIRS + onestripe))
6029         cmd="$LFS find -stripe-count +0 -type f $dir"
6030         nums=$($cmd | wc -l)
6031         [ $nums -eq $expected ] || {
6032                 $LFS getstripe -R $dir
6033                 error "'$cmd' wrong: found $nums, expected $expected"
6034         }
6035
6036         expected=$onestripe
6037         cmd="$LFS find -stripe-count 1 -type f $dir"
6038         nums=$($cmd | wc -l)
6039         [ $nums -eq $expected ] || {
6040                 $LFS getstripe -R $dir
6041                 error "'$cmd' wrong: found $nums, expected $expected"
6042         }
6043
6044         cmd="$LFS find -stripe-count -2 -type f $dir"
6045         nums=$($cmd | wc -l)
6046         [ $nums -eq $expected ] || {
6047                 $LFS getstripe -R $dir
6048                 error "'$cmd' wrong: found $nums, expected $expected"
6049         }
6050
6051         expected=0
6052         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
6053         nums=$($cmd | wc -l)
6054         [ $nums -eq $expected ] || {
6055                 $LFS getstripe -R $dir
6056                 error "'$cmd' wrong: found $nums, expected $expected"
6057         }
6058 }
6059 run_test 56s "check lfs find -stripe-count works"
6060
6061 test_56t() { # LU-611 #LU-9369
6062         local dir=$DIR/$tdir
6063
6064         setup_56 $dir 0 $NUMDIRS
6065         for i in $(seq $NUMDIRS); do
6066                 $LFS setstripe -S 8M $dir/dir$i/$tfile
6067         done
6068
6069         local expected=$NUMDIRS
6070         local cmd="$LFS find -S 8M $dir"
6071         local nums=$($cmd | wc -l)
6072
6073         [ $nums -eq $expected ] || {
6074                 $LFS getstripe -R $dir
6075                 error "'$cmd' wrong: found $nums, expected $expected"
6076         }
6077         rm -rf $dir
6078
6079         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
6080
6081         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
6082
6083         expected=$(((NUMDIRS + 1) * NUMFILES))
6084         cmd="$LFS find -stripe-size 512k -type f $dir"
6085         nums=$($cmd | wc -l)
6086         [ $nums -eq $expected ] ||
6087                 error "'$cmd' wrong: found $nums, expected $expected"
6088
6089         cmd="$LFS find -stripe-size +320k -type f $dir"
6090         nums=$($cmd | wc -l)
6091         [ $nums -eq $expected ] ||
6092                 error "'$cmd' wrong: found $nums, expected $expected"
6093
6094         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
6095         cmd="$LFS find -stripe-size +200k -type f $dir"
6096         nums=$($cmd | wc -l)
6097         [ $nums -eq $expected ] ||
6098                 error "'$cmd' wrong: found $nums, expected $expected"
6099
6100         cmd="$LFS find -stripe-size -640k -type f $dir"
6101         nums=$($cmd | wc -l)
6102         [ $nums -eq $expected ] ||
6103                 error "'$cmd' wrong: found $nums, expected $expected"
6104
6105         expected=4
6106         cmd="$LFS find -stripe-size 256k -type f $dir"
6107         nums=$($cmd | wc -l)
6108         [ $nums -eq $expected ] ||
6109                 error "'$cmd' wrong: found $nums, expected $expected"
6110
6111         cmd="$LFS find -stripe-size -320k -type f $dir"
6112         nums=$($cmd | wc -l)
6113         [ $nums -eq $expected ] ||
6114                 error "'$cmd' wrong: found $nums, expected $expected"
6115
6116         expected=0
6117         cmd="$LFS find -stripe-size 1024k -type f $dir"
6118         nums=$($cmd | wc -l)
6119         [ $nums -eq $expected ] ||
6120                 error "'$cmd' wrong: found $nums, expected $expected"
6121 }
6122 run_test 56t "check lfs find -stripe-size works"
6123
6124 test_56u() { # LU-611
6125         local dir=$DIR/$tdir
6126
6127         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
6128
6129         if [[ $OSTCOUNT -gt 1 ]]; then
6130                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
6131                 onestripe=4
6132         else
6133                 onestripe=0
6134         fi
6135
6136         local expected=$(((NUMDIRS + 1) * NUMFILES))
6137         local cmd="$LFS find -stripe-index 0 -type f $dir"
6138         local nums=$($cmd | wc -l)
6139
6140         [ $nums -eq $expected ] ||
6141                 error "'$cmd' wrong: found $nums, expected $expected"
6142
6143         expected=$onestripe
6144         cmd="$LFS find -stripe-index 1 -type f $dir"
6145         nums=$($cmd | wc -l)
6146         [ $nums -eq $expected ] ||
6147                 error "'$cmd' wrong: found $nums, expected $expected"
6148
6149         cmd="$LFS find ! -stripe-index 0 -type f $dir"
6150         nums=$($cmd | wc -l)
6151         [ $nums -eq $expected ] ||
6152                 error "'$cmd' wrong: found $nums, expected $expected"
6153
6154         expected=0
6155         # This should produce an error and not return any files
6156         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
6157         nums=$($cmd 2>/dev/null | wc -l)
6158         [ $nums -eq $expected ] ||
6159                 error "'$cmd' wrong: found $nums, expected $expected"
6160
6161         if [[ $OSTCOUNT -gt 1 ]]; then
6162                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
6163                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
6164                 nums=$($cmd | wc -l)
6165                 [ $nums -eq $expected ] ||
6166                         error "'$cmd' wrong: found $nums, expected $expected"
6167         fi
6168 }
6169 run_test 56u "check lfs find -stripe-index works"
6170
6171 test_56v() {
6172         local mdt_idx=0
6173         local dir=$DIR/$tdir
6174
6175         setup_56 $dir $NUMFILES $NUMDIRS
6176
6177         UUID=$(mdtuuid_from_index $mdt_idx $dir)
6178         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
6179
6180         for file in $($LFS find -m $UUID $dir); do
6181                 file_midx=$($LFS getstripe -m $file)
6182                 [ $file_midx -eq $mdt_idx ] ||
6183                         error "lfs find -m $UUID != getstripe -m $file_midx"
6184         done
6185 }
6186 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6187
6188 test_56w() {
6189         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6190         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6191
6192         local dir=$DIR/$tdir
6193
6194         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6195
6196         local stripe_size=$($LFS getstripe -S -d $dir) ||
6197                 error "$LFS getstripe -S -d $dir failed"
6198         stripe_size=${stripe_size%% *}
6199
6200         local file_size=$((stripe_size * OSTCOUNT))
6201         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6202         local required_space=$((file_num * file_size))
6203         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6204                            head -n1)
6205         [[ $free_space -le $((required_space / 1024)) ]] &&
6206                 skip_env "need $required_space, have $free_space kbytes"
6207
6208         local dd_bs=65536
6209         local dd_count=$((file_size / dd_bs))
6210
6211         # write data into the files
6212         local i
6213         local j
6214         local file
6215
6216         for i in $(seq $NUMFILES); do
6217                 file=$dir/file$i
6218                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6219                         error "write data into $file failed"
6220         done
6221         for i in $(seq $NUMDIRS); do
6222                 for j in $(seq $NUMFILES); do
6223                         file=$dir/dir$i/file$j
6224                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6225                                 error "write data into $file failed"
6226                 done
6227         done
6228
6229         # $LFS_MIGRATE will fail if hard link migration is unsupported
6230         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
6231                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6232                         error "creating links to $dir/dir1/file1 failed"
6233         fi
6234
6235         local expected=-1
6236
6237         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6238
6239         # lfs_migrate file
6240         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6241
6242         echo "$cmd"
6243         eval $cmd || error "$cmd failed"
6244
6245         check_stripe_count $dir/file1 $expected
6246
6247         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6248         then
6249                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6250                 # OST 1 if it is on OST 0. This file is small enough to
6251                 # be on only one stripe.
6252                 file=$dir/migr_1_ost
6253                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6254                         error "write data into $file failed"
6255                 local obdidx=$($LFS getstripe -i $file)
6256                 local oldmd5=$(md5sum $file)
6257                 local newobdidx=0
6258
6259                 [[ $obdidx -eq 0 ]] && newobdidx=1
6260                 cmd="$LFS migrate -i $newobdidx $file"
6261                 echo $cmd
6262                 eval $cmd || error "$cmd failed"
6263
6264                 local realobdix=$($LFS getstripe -i $file)
6265                 local newmd5=$(md5sum $file)
6266
6267                 [[ $newobdidx -ne $realobdix ]] &&
6268                         error "new OST is different (was=$obdidx, "\
6269                               "wanted=$newobdidx, got=$realobdix)"
6270                 [[ "$oldmd5" != "$newmd5" ]] &&
6271                         error "md5sum differ: $oldmd5, $newmd5"
6272         fi
6273
6274         # lfs_migrate dir
6275         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6276         echo "$cmd"
6277         eval $cmd || error "$cmd failed"
6278
6279         for j in $(seq $NUMFILES); do
6280                 check_stripe_count $dir/dir1/file$j $expected
6281         done
6282
6283         # lfs_migrate works with lfs find
6284         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6285              $LFS_MIGRATE -y -c $expected"
6286         echo "$cmd"
6287         eval $cmd || error "$cmd failed"
6288
6289         for i in $(seq 2 $NUMFILES); do
6290                 check_stripe_count $dir/file$i $expected
6291         done
6292         for i in $(seq 2 $NUMDIRS); do
6293                 for j in $(seq $NUMFILES); do
6294                 check_stripe_count $dir/dir$i/file$j $expected
6295                 done
6296         done
6297 }
6298 run_test 56w "check lfs_migrate -c stripe_count works"
6299
6300 test_56wb() {
6301         local file1=$DIR/$tdir/file1
6302         local create_pool=false
6303         local initial_pool=$($LFS getstripe -p $DIR)
6304         local pool_list=()
6305         local pool=""
6306
6307         echo -n "Creating test dir..."
6308         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6309         echo "done."
6310
6311         echo -n "Creating test file..."
6312         touch $file1 || error "cannot create file"
6313         echo "done."
6314
6315         echo -n "Detecting existing pools..."
6316         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6317
6318         if [ ${#pool_list[@]} -gt 0 ]; then
6319                 echo "${pool_list[@]}"
6320                 for thispool in "${pool_list[@]}"; do
6321                         if [[ -z "$initial_pool" ||
6322                               "$initial_pool" != "$thispool" ]]; then
6323                                 pool="$thispool"
6324                                 echo "Using existing pool '$pool'"
6325                                 break
6326                         fi
6327                 done
6328         else
6329                 echo "none detected."
6330         fi
6331         if [ -z "$pool" ]; then
6332                 pool=${POOL:-testpool}
6333                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6334                 echo -n "Creating pool '$pool'..."
6335                 create_pool=true
6336                 pool_add $pool &> /dev/null ||
6337                         error "pool_add failed"
6338                 echo "done."
6339
6340                 echo -n "Adding target to pool..."
6341                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6342                         error "pool_add_targets failed"
6343                 echo "done."
6344         fi
6345
6346         echo -n "Setting pool using -p option..."
6347         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6348                 error "migrate failed rc = $?"
6349         echo "done."
6350
6351         echo -n "Verifying test file is in pool after migrating..."
6352         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6353                 error "file was not migrated to pool $pool"
6354         echo "done."
6355
6356         echo -n "Removing test file from pool '$pool'..."
6357         $LFS migrate $file1 &> /dev/null ||
6358                 error "cannot remove from pool"
6359         [ "$($LFS getstripe -p $file1)" ] &&
6360                 error "pool still set"
6361         echo "done."
6362
6363         echo -n "Setting pool using --pool option..."
6364         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6365                 error "migrate failed rc = $?"
6366         echo "done."
6367
6368         # Clean up
6369         rm -f $file1
6370         if $create_pool; then
6371                 destroy_test_pools 2> /dev/null ||
6372                         error "destroy test pools failed"
6373         fi
6374 }
6375 run_test 56wb "check lfs_migrate pool support"
6376
6377 test_56wc() {
6378         local file1="$DIR/$tdir/file1"
6379
6380         echo -n "Creating test dir..."
6381         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6382         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6383         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6384                 error "cannot set stripe"
6385         echo "done"
6386
6387         echo -n "Setting initial stripe for test file..."
6388         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6389                 error "cannot set stripe"
6390         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6391                 error "stripe size not set"
6392         echo "done."
6393
6394         # File currently set to -S 512K -c 1
6395
6396         # Ensure -c and -S options are rejected when -R is set
6397         echo -n "Verifying incompatible options are detected..."
6398         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6399                 error "incompatible -c and -R options not detected"
6400         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6401                 error "incompatible -S and -R options not detected"
6402         echo "done."
6403
6404         # Ensure unrecognized options are passed through to 'lfs migrate'
6405         echo -n "Verifying -S option is passed through to lfs migrate..."
6406         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6407                 error "migration failed"
6408         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6409                 error "file was not restriped"
6410         echo "done."
6411
6412         # File currently set to -S 1M -c 1
6413
6414         # Ensure long options are supported
6415         echo -n "Verifying long options supported..."
6416         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6417                 error "long option without argument not supported"
6418         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6419                 error "long option with argument not supported"
6420         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6421                 error "file not restriped with --stripe-size option"
6422         echo "done."
6423
6424         # File currently set to -S 512K -c 1
6425
6426         if [ "$OSTCOUNT" -gt 1 ]; then
6427                 echo -n "Verifying explicit stripe count can be set..."
6428                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6429                         error "migrate failed"
6430                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6431                         error "file not restriped to explicit count"
6432                 echo "done."
6433         fi
6434
6435         # File currently set to -S 512K -c 1 or -S 512K -c 2
6436
6437         # Ensure parent striping is used if -R is set, and no stripe
6438         # count or size is specified
6439         echo -n "Setting stripe for parent directory..."
6440         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6441                 error "cannot set stripe"
6442         echo "done."
6443
6444         echo -n "Verifying restripe option uses parent stripe settings..."
6445         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6446                 error "migrate failed"
6447         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6448                 error "file not restriped to parent settings"
6449         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6450                 error "file not restriped to parent settings"
6451         echo "done."
6452
6453         # File currently set to -S 1M -c 1
6454
6455         # Ensure striping is preserved if -R is not set, and no stripe
6456         # count or size is specified
6457         echo -n "Verifying striping size preserved when not specified..."
6458         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6459         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6460                 error "cannot set stripe on parent directory"
6461         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6462                 error "migrate failed"
6463         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6464                 error "file was restriped"
6465         echo "done."
6466
6467         # Ensure file name properly detected when final option has no argument
6468         echo -n "Verifying file name properly detected..."
6469         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6470                 error "file name interpreted as option argument"
6471         echo "done."
6472
6473         # Clean up
6474         rm -f "$file1"
6475 }
6476 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6477
6478 test_56wd() {
6479         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6480
6481         local file1=$DIR/$tdir/file1
6482
6483         echo -n "Creating test dir..."
6484         test_mkdir $DIR/$tdir || error "cannot create dir"
6485         echo "done."
6486
6487         echo -n "Creating test file..."
6488         touch $file1
6489         echo "done."
6490
6491         # Ensure 'lfs migrate' will fail by using a non-existent option,
6492         # and make sure rsync is not called to recover
6493         echo -n "Make sure --no-rsync option works..."
6494         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6495                 grep -q 'refusing to fall back to rsync' ||
6496                 error "rsync was called with --no-rsync set"
6497         echo "done."
6498
6499         # Ensure rsync is called without trying 'lfs migrate' first
6500         echo -n "Make sure --rsync option works..."
6501         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6502                 grep -q 'falling back to rsync' &&
6503                 error "lfs migrate was called with --rsync set"
6504         echo "done."
6505
6506         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6507         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6508                 grep -q 'at the same time' ||
6509                 error "--rsync and --no-rsync accepted concurrently"
6510         echo "done."
6511
6512         # Clean up
6513         rm -f $file1
6514 }
6515 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6516
6517 test_56x() {
6518         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6519         check_swap_layouts_support
6520
6521         local dir=$DIR/$tdir
6522         local ref1=/etc/passwd
6523         local file1=$dir/file1
6524
6525         test_mkdir $dir || error "creating dir $dir"
6526         $LFS setstripe -c 2 $file1
6527         cp $ref1 $file1
6528         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6529         stripe=$($LFS getstripe -c $file1)
6530         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6531         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6532
6533         # clean up
6534         rm -f $file1
6535 }
6536 run_test 56x "lfs migration support"
6537
6538 test_56xa() {
6539         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6540         check_swap_layouts_support
6541
6542         local dir=$DIR/$tdir/$testnum
6543
6544         test_mkdir -p $dir
6545
6546         local ref1=/etc/passwd
6547         local file1=$dir/file1
6548
6549         $LFS setstripe -c 2 $file1
6550         cp $ref1 $file1
6551         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6552
6553         local stripe=$($LFS getstripe -c $file1)
6554
6555         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6556         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6557
6558         # clean up
6559         rm -f $file1
6560 }
6561 run_test 56xa "lfs migration --block support"
6562
6563 check_migrate_links() {
6564         local dir="$1"
6565         local file1="$dir/file1"
6566         local begin="$2"
6567         local count="$3"
6568         local total_count=$(($begin + $count - 1))
6569         local symlink_count=10
6570         local uniq_count=10
6571
6572         if [ ! -f "$file1" ]; then
6573                 echo -n "creating initial file..."
6574                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6575                         error "cannot setstripe initial file"
6576                 echo "done"
6577
6578                 echo -n "creating symlinks..."
6579                 for s in $(seq 1 $symlink_count); do
6580                         ln -s "$file1" "$dir/slink$s" ||
6581                                 error "cannot create symlinks"
6582                 done
6583                 echo "done"
6584
6585                 echo -n "creating nonlinked files..."
6586                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6587                         error "cannot create nonlinked files"
6588                 echo "done"
6589         fi
6590
6591         # create hard links
6592         if [ ! -f "$dir/file$total_count" ]; then
6593                 echo -n "creating hard links $begin:$total_count..."
6594                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6595                         /dev/null || error "cannot create hard links"
6596                 echo "done"
6597         fi
6598
6599         echo -n "checking number of hard links listed in xattrs..."
6600         local fid=$($LFS getstripe -F "$file1")
6601         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6602
6603         echo "${#paths[*]}"
6604         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6605                         skip "hard link list has unexpected size, skipping test"
6606         fi
6607         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6608                         error "link names should exceed xattrs size"
6609         fi
6610
6611         echo -n "migrating files..."
6612         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6613         local rc=$?
6614         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6615         echo "done"
6616
6617         # make sure all links have been properly migrated
6618         echo -n "verifying files..."
6619         fid=$($LFS getstripe -F "$file1") ||
6620                 error "cannot get fid for file $file1"
6621         for i in $(seq 2 $total_count); do
6622                 local fid2=$($LFS getstripe -F $dir/file$i)
6623
6624                 [ "$fid2" == "$fid" ] ||
6625                         error "migrated hard link has mismatched FID"
6626         done
6627
6628         # make sure hard links were properly detected, and migration was
6629         # performed only once for the entire link set; nonlinked files should
6630         # also be migrated
6631         local actual=$(grep -c 'done' <<< "$migrate_out")
6632         local expected=$(($uniq_count + 1))
6633
6634         [ "$actual" -eq  "$expected" ] ||
6635                 error "hard links individually migrated ($actual != $expected)"
6636
6637         # make sure the correct number of hard links are present
6638         local hardlinks=$(stat -c '%h' "$file1")
6639
6640         [ $hardlinks -eq $total_count ] ||
6641                 error "num hard links $hardlinks != $total_count"
6642         echo "done"
6643
6644         return 0
6645 }
6646
6647 test_56xb() {
6648         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6649                 skip "Need MDS version at least 2.10.55"
6650
6651         local dir="$DIR/$tdir"
6652
6653         test_mkdir "$dir" || error "cannot create dir $dir"
6654
6655         echo "testing lfs migrate mode when all links fit within xattrs"
6656         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6657
6658         echo "testing rsync mode when all links fit within xattrs"
6659         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6660
6661         echo "testing lfs migrate mode when all links do not fit within xattrs"
6662         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6663
6664         echo "testing rsync mode when all links do not fit within xattrs"
6665         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6666
6667
6668         # clean up
6669         rm -rf $dir
6670 }
6671 run_test 56xb "lfs migration hard link support"
6672
6673 test_56xc() {
6674         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6675
6676         local dir="$DIR/$tdir"
6677
6678         test_mkdir "$dir" || error "cannot create dir $dir"
6679
6680         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6681         echo -n "Setting initial stripe for 20MB test file..."
6682         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6683                 error "cannot setstripe 20MB file"
6684         echo "done"
6685         echo -n "Sizing 20MB test file..."
6686         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6687         echo "done"
6688         echo -n "Verifying small file autostripe count is 1..."
6689         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6690                 error "cannot migrate 20MB file"
6691         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6692                 error "cannot get stripe for $dir/20mb"
6693         [ $stripe_count -eq 1 ] ||
6694                 error "unexpected stripe count $stripe_count for 20MB file"
6695         rm -f "$dir/20mb"
6696         echo "done"
6697
6698         # Test 2: File is small enough to fit within the available space on
6699         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6700         # have at least an additional 1KB for each desired stripe for test 3
6701         echo -n "Setting stripe for 1GB test file..."
6702         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6703         echo "done"
6704         echo -n "Sizing 1GB test file..."
6705         # File size is 1GB + 3KB
6706         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6707         echo "done"
6708
6709         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6710         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6711         if (( avail > 524288 * OSTCOUNT )); then
6712                 echo -n "Migrating 1GB file..."
6713                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6714                         error "cannot migrate 1GB file"
6715                 echo "done"
6716                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6717                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6718                         error "cannot getstripe for 1GB file"
6719                 [ $stripe_count -eq 2 ] ||
6720                         error "unexpected stripe count $stripe_count != 2"
6721                 echo "done"
6722         fi
6723
6724         # Test 3: File is too large to fit within the available space on
6725         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6726         if [ $OSTCOUNT -ge 3 ]; then
6727                 # The required available space is calculated as
6728                 # file size (1GB + 3KB) / OST count (3).
6729                 local kb_per_ost=349526
6730
6731                 echo -n "Migrating 1GB file with limit..."
6732                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6733                         error "cannot migrate 1GB file with limit"
6734                 echo "done"
6735
6736                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6737                 echo -n "Verifying 1GB autostripe count with limited space..."
6738                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6739                         error "unexpected stripe count $stripe_count (min 3)"
6740                 echo "done"
6741         fi
6742
6743         # clean up
6744         rm -rf $dir
6745 }
6746 run_test 56xc "lfs migration autostripe"
6747
6748 test_56y() {
6749         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6750                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6751
6752         local res=""
6753         local dir=$DIR/$tdir
6754         local f1=$dir/file1
6755         local f2=$dir/file2
6756
6757         test_mkdir -p $dir || error "creating dir $dir"
6758         touch $f1 || error "creating std file $f1"
6759         $MULTIOP $f2 H2c || error "creating released file $f2"
6760
6761         # a directory can be raid0, so ask only for files
6762         res=$($LFS find $dir -L raid0 -type f | wc -l)
6763         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6764
6765         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6766         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6767
6768         # only files can be released, so no need to force file search
6769         res=$($LFS find $dir -L released)
6770         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6771
6772         res=$($LFS find $dir -type f \! -L released)
6773         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6774 }
6775 run_test 56y "lfs find -L raid0|released"
6776
6777 test_56z() { # LU-4824
6778         # This checks to make sure 'lfs find' continues after errors
6779         # There are two classes of errors that should be caught:
6780         # - If multiple paths are provided, all should be searched even if one
6781         #   errors out
6782         # - If errors are encountered during the search, it should not terminate
6783         #   early
6784         local dir=$DIR/$tdir
6785         local i
6786
6787         test_mkdir $dir
6788         for i in d{0..9}; do
6789                 test_mkdir $dir/$i
6790                 touch $dir/$i/$tfile
6791         done
6792         $LFS find $DIR/non_existent_dir $dir &&
6793                 error "$LFS find did not return an error"
6794         # Make a directory unsearchable. This should NOT be the last entry in
6795         # directory order.  Arbitrarily pick the 6th entry
6796         chmod 700 $($LFS find $dir -type d | sed '6!d')
6797
6798         $RUNAS $LFS find $DIR/non_existent $dir
6799         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6800
6801         # The user should be able to see 10 directories and 9 files
6802         (( count == 19 )) ||
6803                 error "$LFS find found $count != 19 entries after error"
6804 }
6805 run_test 56z "lfs find should continue after an error"
6806
6807 test_56aa() { # LU-5937
6808         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6809
6810         local dir=$DIR/$tdir
6811
6812         mkdir $dir
6813         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6814
6815         createmany -o $dir/striped_dir/${tfile}- 1024
6816         local dirs=$($LFS find --size +8k $dir/)
6817
6818         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6819 }
6820 run_test 56aa "lfs find --size under striped dir"
6821
6822 test_56ab() { # LU-10705
6823         test_mkdir $DIR/$tdir
6824         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6825         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6826         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6827         # Flush writes to ensure valid blocks.  Need to be more thorough for
6828         # ZFS, since blocks are not allocated/returned to client immediately.
6829         sync_all_data
6830         wait_zfs_commit ost1 2
6831         cancel_lru_locks osc
6832         ls -ls $DIR/$tdir
6833
6834         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6835
6836         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6837
6838         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6839         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6840
6841         rm -f $DIR/$tdir/$tfile.[123]
6842 }
6843 run_test 56ab "lfs find --blocks"
6844
6845 test_56ba() {
6846         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6847                 skip "Need MDS version at least 2.10.50"
6848
6849         # Create composite files with one component
6850         local dir=$DIR/$tdir
6851
6852         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6853         # Create composite files with three components
6854         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6855         # Create non-composite files
6856         createmany -o $dir/${tfile}- 10
6857
6858         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6859
6860         [[ $nfiles == 10 ]] ||
6861                 error "lfs find -E 1M found $nfiles != 10 files"
6862
6863         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6864         [[ $nfiles == 25 ]] ||
6865                 error "lfs find ! -E 1M found $nfiles != 25 files"
6866
6867         # All files have a component that starts at 0
6868         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6869         [[ $nfiles == 35 ]] ||
6870                 error "lfs find --component-start 0 - $nfiles != 35 files"
6871
6872         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6873         [[ $nfiles == 15 ]] ||
6874                 error "lfs find --component-start 2M - $nfiles != 15 files"
6875
6876         # All files created here have a componenet that does not starts at 2M
6877         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6878         [[ $nfiles == 35 ]] ||
6879                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6880
6881         # Find files with a specified number of components
6882         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6883         [[ $nfiles == 15 ]] ||
6884                 error "lfs find --component-count 3 - $nfiles != 15 files"
6885
6886         # Remember non-composite files have a component count of zero
6887         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6888         [[ $nfiles == 10 ]] ||
6889                 error "lfs find --component-count 0 - $nfiles != 10 files"
6890
6891         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6892         [[ $nfiles == 20 ]] ||
6893                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6894
6895         # All files have a flag called "init"
6896         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6897         [[ $nfiles == 35 ]] ||
6898                 error "lfs find --component-flags init - $nfiles != 35 files"
6899
6900         # Multi-component files will have a component not initialized
6901         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6902         [[ $nfiles == 15 ]] ||
6903                 error "lfs find !--component-flags init - $nfiles != 15 files"
6904
6905         rm -rf $dir
6906
6907 }
6908 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6909
6910 test_56ca() {
6911         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6912                 skip "Need MDS version at least 2.10.57"
6913
6914         local td=$DIR/$tdir
6915         local tf=$td/$tfile
6916         local dir
6917         local nfiles
6918         local cmd
6919         local i
6920         local j
6921
6922         # create mirrored directories and mirrored files
6923         mkdir $td || error "mkdir $td failed"
6924         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6925         createmany -o $tf- 10 || error "create $tf- failed"
6926
6927         for i in $(seq 2); do
6928                 dir=$td/dir$i
6929                 mkdir $dir || error "mkdir $dir failed"
6930                 $LFS mirror create -N$((3 + i)) $dir ||
6931                         error "create mirrored dir $dir failed"
6932                 createmany -o $dir/$tfile- 10 ||
6933                         error "create $dir/$tfile- failed"
6934         done
6935
6936         # change the states of some mirrored files
6937         echo foo > $tf-6
6938         for i in $(seq 2); do
6939                 dir=$td/dir$i
6940                 for j in $(seq 4 9); do
6941                         echo foo > $dir/$tfile-$j
6942                 done
6943         done
6944
6945         # find mirrored files with specific mirror count
6946         cmd="$LFS find --mirror-count 3 --type f $td"
6947         nfiles=$($cmd | wc -l)
6948         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6949
6950         cmd="$LFS find ! --mirror-count 3 --type f $td"
6951         nfiles=$($cmd | wc -l)
6952         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6953
6954         cmd="$LFS find --mirror-count +2 --type f $td"
6955         nfiles=$($cmd | wc -l)
6956         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6957
6958         cmd="$LFS find --mirror-count -6 --type f $td"
6959         nfiles=$($cmd | wc -l)
6960         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6961
6962         # find mirrored files with specific file state
6963         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6964         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6965
6966         cmd="$LFS find --mirror-state=ro --type f $td"
6967         nfiles=$($cmd | wc -l)
6968         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6969
6970         cmd="$LFS find ! --mirror-state=ro --type f $td"
6971         nfiles=$($cmd | wc -l)
6972         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6973
6974         cmd="$LFS find --mirror-state=wp --type f $td"
6975         nfiles=$($cmd | wc -l)
6976         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6977
6978         cmd="$LFS find ! --mirror-state=sp --type f $td"
6979         nfiles=$($cmd | wc -l)
6980         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6981 }
6982 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6983
6984 test_57a() {
6985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6986         # note test will not do anything if MDS is not local
6987         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6988                 skip_env "ldiskfs only test"
6989         fi
6990         remote_mds_nodsh && skip "remote MDS with nodsh"
6991
6992         local MNTDEV="osd*.*MDT*.mntdev"
6993         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6994         [ -z "$DEV" ] && error "can't access $MNTDEV"
6995         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6996                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6997                         error "can't access $DEV"
6998                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6999                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
7000                 rm $TMP/t57a.dump
7001         done
7002 }
7003 run_test 57a "verify MDS filesystem created with large inodes =="
7004
7005 test_57b() {
7006         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7007         if [ "$mds1_FSTYPE" != ldiskfs ]; then
7008                 skip_env "ldiskfs only test"
7009         fi
7010         remote_mds_nodsh && skip "remote MDS with nodsh"
7011
7012         local dir=$DIR/$tdir
7013         local filecount=100
7014         local file1=$dir/f1
7015         local fileN=$dir/f$filecount
7016
7017         rm -rf $dir || error "removing $dir"
7018         test_mkdir -c1 $dir
7019         local mdtidx=$($LFS getstripe -m $dir)
7020         local mdtname=MDT$(printf %04x $mdtidx)
7021         local facet=mds$((mdtidx + 1))
7022
7023         echo "mcreating $filecount files"
7024         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
7025
7026         # verify that files do not have EAs yet
7027         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
7028                 error "$file1 has an EA"
7029         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
7030                 error "$fileN has an EA"
7031
7032         sync
7033         sleep 1
7034         df $dir  #make sure we get new statfs data
7035         local mdsfree=$(do_facet $facet \
7036                         lctl get_param -n osd*.*$mdtname.kbytesfree)
7037         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7038         local file
7039
7040         echo "opening files to create objects/EAs"
7041         for file in $(seq -f $dir/f%g 1 $filecount); do
7042                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
7043                         error "opening $file"
7044         done
7045
7046         # verify that files have EAs now
7047         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
7048         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
7049
7050         sleep 1  #make sure we get new statfs data
7051         df $dir
7052         local mdsfree2=$(do_facet $facet \
7053                          lctl get_param -n osd*.*$mdtname.kbytesfree)
7054         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
7055
7056         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
7057                 if [ "$mdsfree" != "$mdsfree2" ]; then
7058                         error "MDC before $mdcfree != after $mdcfree2"
7059                 else
7060                         echo "MDC before $mdcfree != after $mdcfree2"
7061                         echo "unable to confirm if MDS has large inodes"
7062                 fi
7063         fi
7064         rm -rf $dir
7065 }
7066 run_test 57b "default LOV EAs are stored inside large inodes ==="
7067
7068 test_58() {
7069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7070         [ -z "$(which wiretest 2>/dev/null)" ] &&
7071                         skip_env "could not find wiretest"
7072
7073         wiretest
7074 }
7075 run_test 58 "verify cross-platform wire constants =============="
7076
7077 test_59() {
7078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7079
7080         echo "touch 130 files"
7081         createmany -o $DIR/f59- 130
7082         echo "rm 130 files"
7083         unlinkmany $DIR/f59- 130
7084         sync
7085         # wait for commitment of removal
7086         wait_delete_completed
7087 }
7088 run_test 59 "verify cancellation of llog records async ========="
7089
7090 TEST60_HEAD="test_60 run $RANDOM"
7091 test_60a() {
7092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7093         remote_mgs_nodsh && skip "remote MGS with nodsh"
7094         do_facet mgs "! which run-llog.sh &> /dev/null" &&
7095                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
7096                         skip_env "missing subtest run-llog.sh"
7097
7098         log "$TEST60_HEAD - from kernel mode"
7099         do_facet mgs "$LCTL dk > /dev/null"
7100         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
7101         do_facet mgs $LCTL dk > $TMP/$tfile
7102
7103         # LU-6388: test llog_reader
7104         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
7105         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
7106         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
7107                         skip_env "missing llog_reader"
7108         local fstype=$(facet_fstype mgs)
7109         [ $fstype != ldiskfs -a $fstype != zfs ] &&
7110                 skip_env "Only for ldiskfs or zfs type mgs"
7111
7112         local mntpt=$(facet_mntpt mgs)
7113         local mgsdev=$(mgsdevname 1)
7114         local fid_list
7115         local fid
7116         local rec_list
7117         local rec
7118         local rec_type
7119         local obj_file
7120         local path
7121         local seq
7122         local oid
7123         local pass=true
7124
7125         #get fid and record list
7126         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
7127                 tail -n 4))
7128         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
7129                 tail -n 4))
7130         #remount mgs as ldiskfs or zfs type
7131         stop mgs || error "stop mgs failed"
7132         mount_fstype mgs || error "remount mgs failed"
7133         for ((i = 0; i < ${#fid_list[@]}; i++)); do
7134                 fid=${fid_list[i]}
7135                 rec=${rec_list[i]}
7136                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
7137                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
7138                 oid=$((16#$oid))
7139
7140                 case $fstype in
7141                         ldiskfs )
7142                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
7143                         zfs )
7144                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
7145                 esac
7146                 echo "obj_file is $obj_file"
7147                 do_facet mgs $llog_reader $obj_file
7148
7149                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
7150                         awk '{ print $3 }' | sed -e "s/^type=//g")
7151                 if [ $rec_type != $rec ]; then
7152                         echo "FAILED test_60a wrong record type $rec_type," \
7153                               "should be $rec"
7154                         pass=false
7155                         break
7156                 fi
7157
7158                 #check obj path if record type is LLOG_LOGID_MAGIC
7159                 if [ "$rec" == "1064553b" ]; then
7160                         path=$(do_facet mgs $llog_reader $obj_file |
7161                                 grep "path=" | awk '{ print $NF }' |
7162                                 sed -e "s/^path=//g")
7163                         if [ $obj_file != $mntpt/$path ]; then
7164                                 echo "FAILED test_60a wrong obj path" \
7165                                       "$montpt/$path, should be $obj_file"
7166                                 pass=false
7167                                 break
7168                         fi
7169                 fi
7170         done
7171         rm -f $TMP/$tfile
7172         #restart mgs before "error", otherwise it will block the next test
7173         stop mgs || error "stop mgs failed"
7174         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
7175         $pass || error "test failed, see FAILED test_60a messages for specifics"
7176 }
7177 run_test 60a "llog_test run from kernel module and test llog_reader"
7178
7179 test_60b() { # bug 6411
7180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7181
7182         dmesg > $DIR/$tfile
7183         LLOG_COUNT=$(do_facet mgs dmesg |
7184                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7185                           /llog_[a-z]*.c:[0-9]/ {
7186                                 if (marker)
7187                                         from_marker++
7188                                 from_begin++
7189                           }
7190                           END {
7191                                 if (marker)
7192                                         print from_marker
7193                                 else
7194                                         print from_begin
7195                           }")
7196
7197         [[ $LLOG_COUNT -gt 120 ]] &&
7198                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7199 }
7200 run_test 60b "limit repeated messages from CERROR/CWARN"
7201
7202 test_60c() {
7203         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7204
7205         echo "create 5000 files"
7206         createmany -o $DIR/f60c- 5000
7207 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7208         lctl set_param fail_loc=0x80000137
7209         unlinkmany $DIR/f60c- 5000
7210         lctl set_param fail_loc=0
7211 }
7212 run_test 60c "unlink file when mds full"
7213
7214 test_60d() {
7215         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7216
7217         SAVEPRINTK=$(lctl get_param -n printk)
7218         # verify "lctl mark" is even working"
7219         MESSAGE="test message ID $RANDOM $$"
7220         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7221         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7222
7223         lctl set_param printk=0 || error "set lnet.printk failed"
7224         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7225         MESSAGE="new test message ID $RANDOM $$"
7226         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7227         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7228         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7229
7230         lctl set_param -n printk="$SAVEPRINTK"
7231 }
7232 run_test 60d "test printk console message masking"
7233
7234 test_60e() {
7235         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7236         remote_mds_nodsh && skip "remote MDS with nodsh"
7237
7238         touch $DIR/$tfile
7239 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7240         do_facet mds1 lctl set_param fail_loc=0x15b
7241         rm $DIR/$tfile
7242 }
7243 run_test 60e "no space while new llog is being created"
7244
7245 test_60g() {
7246         local pid
7247         local i
7248
7249         test_mkdir -c $MDSCOUNT $DIR/$tdir
7250
7251         (
7252                 local index=0
7253                 while true; do
7254                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7255                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7256                                 2>/dev/null
7257                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7258                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7259                         index=$((index + 1))
7260                 done
7261         ) &
7262
7263         pid=$!
7264
7265         for i in {0..100}; do
7266                 # define OBD_FAIL_OSD_TXN_START    0x19a
7267                 local index=$((i % MDSCOUNT + 1))
7268
7269                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7270                         > /dev/null
7271                 usleep 100
7272         done
7273
7274         kill -9 $pid
7275
7276         for i in $(seq $MDSCOUNT); do
7277                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7278         done
7279
7280         mkdir $DIR/$tdir/new || error "mkdir failed"
7281         rmdir $DIR/$tdir/new || error "rmdir failed"
7282
7283         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7284                 -t namespace
7285         for i in $(seq $MDSCOUNT); do
7286                 wait_update_facet mds$i "$LCTL get_param -n \
7287                         mdd.$(facet_svc mds$i).lfsck_namespace |
7288                         awk '/^status/ { print \\\$2 }'" "completed"
7289         done
7290
7291         ls -R $DIR/$tdir || error "ls failed"
7292         rm -rf $DIR/$tdir || error "rmdir failed"
7293 }
7294 run_test 60g "transaction abort won't cause MDT hung"
7295
7296 test_60h() {
7297         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7298                 skip "Need MDS version at least 2.12.52"
7299         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7300
7301         local f
7302
7303         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7304         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7305         for fail_loc in 0x80000188 0x80000189; do
7306                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7307                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7308                         error "mkdir $dir-$fail_loc failed"
7309                 for i in {0..10}; do
7310                         # create may fail on missing stripe
7311                         echo $i > $DIR/$tdir-$fail_loc/$i
7312                 done
7313                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7314                         error "getdirstripe $tdir-$fail_loc failed"
7315                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7316                         error "migrate $tdir-$fail_loc failed"
7317                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7318                         error "getdirstripe $tdir-$fail_loc failed"
7319                 pushd $DIR/$tdir-$fail_loc
7320                 for f in *; do
7321                         echo $f | cmp $f - || error "$f data mismatch"
7322                 done
7323                 popd
7324                 rm -rf $DIR/$tdir-$fail_loc
7325         done
7326 }
7327 run_test 60h "striped directory with missing stripes can be accessed"
7328
7329 test_61a() {
7330         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7331
7332         f="$DIR/f61"
7333         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7334         cancel_lru_locks osc
7335         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7336         sync
7337 }
7338 run_test 61a "mmap() writes don't make sync hang ================"
7339
7340 test_61b() {
7341         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7342 }
7343 run_test 61b "mmap() of unstriped file is successful"
7344
7345 # bug 2330 - insufficient obd_match error checking causes LBUG
7346 test_62() {
7347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7348
7349         f="$DIR/f62"
7350         echo foo > $f
7351         cancel_lru_locks osc
7352         lctl set_param fail_loc=0x405
7353         cat $f && error "cat succeeded, expect -EIO"
7354         lctl set_param fail_loc=0
7355 }
7356 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7357 # match every page all of the time.
7358 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7359
7360 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7361 # Though this test is irrelevant anymore, it helped to reveal some
7362 # other grant bugs (LU-4482), let's keep it.
7363 test_63a() {   # was test_63
7364         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7365
7366         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7367
7368         for i in `seq 10` ; do
7369                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7370                 sleep 5
7371                 kill $!
7372                 sleep 1
7373         done
7374
7375         rm -f $DIR/f63 || true
7376 }
7377 run_test 63a "Verify oig_wait interruption does not crash ======="
7378
7379 # bug 2248 - async write errors didn't return to application on sync
7380 # bug 3677 - async write errors left page locked
7381 test_63b() {
7382         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7383
7384         debugsave
7385         lctl set_param debug=-1
7386
7387         # ensure we have a grant to do async writes
7388         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7389         rm $DIR/$tfile
7390
7391         sync    # sync lest earlier test intercept the fail_loc
7392
7393         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7394         lctl set_param fail_loc=0x80000406
7395         $MULTIOP $DIR/$tfile Owy && \
7396                 error "sync didn't return ENOMEM"
7397         sync; sleep 2; sync     # do a real sync this time to flush page
7398         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7399                 error "locked page left in cache after async error" || true
7400         debugrestore
7401 }
7402 run_test 63b "async write errors should be returned to fsync ==="
7403
7404 test_64a () {
7405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7406
7407         df $DIR
7408         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7409 }
7410 run_test 64a "verify filter grant calculations (in kernel) ====="
7411
7412 test_64b () {
7413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7414
7415         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7416 }
7417 run_test 64b "check out-of-space detection on client"
7418
7419 test_64c() {
7420         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7421 }
7422 run_test 64c "verify grant shrink"
7423
7424 # this does exactly what osc_request.c:osc_announce_cached() does in
7425 # order to calculate max amount of grants to ask from server
7426 want_grant() {
7427         local tgt=$1
7428
7429         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7430         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7431
7432         ((rpc_in_flight ++));
7433         nrpages=$((nrpages * rpc_in_flight))
7434
7435         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7436
7437         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7438
7439         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7440         local undirty=$((nrpages * PAGE_SIZE))
7441
7442         local max_extent_pages
7443         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7444             grep grant_max_extent_size | awk '{print $2}')
7445         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7446         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7447         local grant_extent_tax
7448         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7449             grep grant_extent_tax | awk '{print $2}')
7450
7451         undirty=$((undirty + nrextents * grant_extent_tax))
7452
7453         echo $undirty
7454 }
7455
7456 # this is size of unit for grant allocation. It should be equal to
7457 # what tgt_grant.c:tgt_grant_chunk() calculates
7458 grant_chunk() {
7459         local tgt=$1
7460         local max_brw_size
7461         local grant_extent_tax
7462
7463         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7464             grep max_brw_size | awk '{print $2}')
7465
7466         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7467             grep grant_extent_tax | awk '{print $2}')
7468
7469         echo $(((max_brw_size + grant_extent_tax) * 2))
7470 }
7471
7472 test_64d() {
7473         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7474                 skip "OST < 2.10.55 doesn't limit grants enough"
7475
7476         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7477         local file=$DIR/$tfile
7478
7479         [[ $($LCTL get_param osc.${tgt}.import |
7480              grep "connect_flags:.*grant_param") ]] ||
7481                 skip "no grant_param connect flag"
7482
7483         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7484
7485         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7486
7487         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7488         stack_trap "rm -f $file" EXIT
7489
7490         $LFS setstripe $file -i 0 -c 1
7491         dd if=/dev/zero of=$file bs=1M count=1000 &
7492         ddpid=$!
7493
7494         while true
7495         do
7496                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7497                 if [[ $cur_grant -gt $max_cur_granted ]]
7498                 then
7499                         kill $ddpid
7500                         error "cur_grant $cur_grant > $max_cur_granted"
7501                 fi
7502                 kill -0 $ddpid
7503                 [[ $? -ne 0 ]] && break;
7504                 sleep 2
7505         done
7506
7507         rm -f $DIR/$tfile
7508         wait_delete_completed
7509         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7510 }
7511 run_test 64d "check grant limit exceed"
7512
7513 # bug 1414 - set/get directories' stripe info
7514 test_65a() {
7515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7516
7517         test_mkdir $DIR/$tdir
7518         touch $DIR/$tdir/f1
7519         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7520 }
7521 run_test 65a "directory with no stripe info"
7522
7523 test_65b() {
7524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7525
7526         test_mkdir $DIR/$tdir
7527         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7528
7529         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7530                                                 error "setstripe"
7531         touch $DIR/$tdir/f2
7532         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7533 }
7534 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7535
7536 test_65c() {
7537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7538         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7539
7540         test_mkdir $DIR/$tdir
7541         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7542
7543         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7544                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7545         touch $DIR/$tdir/f3
7546         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7547 }
7548 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7549
7550 test_65d() {
7551         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7552
7553         test_mkdir $DIR/$tdir
7554         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7555         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7556
7557         if [[ $STRIPECOUNT -le 0 ]]; then
7558                 sc=1
7559         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7560                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7561                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7562         else
7563                 sc=$(($STRIPECOUNT - 1))
7564         fi
7565         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7566         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7567         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7568                 error "lverify failed"
7569 }
7570 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7571
7572 test_65e() {
7573         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7574
7575         test_mkdir $DIR/$tdir
7576
7577         $LFS setstripe $DIR/$tdir || error "setstripe"
7578         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7579                                         error "no stripe info failed"
7580         touch $DIR/$tdir/f6
7581         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7582 }
7583 run_test 65e "directory setstripe defaults"
7584
7585 test_65f() {
7586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7587
7588         test_mkdir $DIR/${tdir}f
7589         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7590                 error "setstripe succeeded" || true
7591 }
7592 run_test 65f "dir setstripe permission (should return error) ==="
7593
7594 test_65g() {
7595         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7596
7597         test_mkdir $DIR/$tdir
7598         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7599
7600         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7601                 error "setstripe -S failed"
7602         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7603         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7604                 error "delete default stripe failed"
7605 }
7606 run_test 65g "directory setstripe -d"
7607
7608 test_65h() {
7609         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7610
7611         test_mkdir $DIR/$tdir
7612         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7613
7614         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7615                 error "setstripe -S failed"
7616         test_mkdir $DIR/$tdir/dd1
7617         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7618                 error "stripe info inherit failed"
7619 }
7620 run_test 65h "directory stripe info inherit ===================="
7621
7622 test_65i() {
7623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7624
7625         save_layout_restore_at_exit $MOUNT
7626
7627         # bug6367: set non-default striping on root directory
7628         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7629
7630         # bug12836: getstripe on -1 default directory striping
7631         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7632
7633         # bug12836: getstripe -v on -1 default directory striping
7634         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7635
7636         # bug12836: new find on -1 default directory striping
7637         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7638 }
7639 run_test 65i "various tests to set root directory striping"
7640
7641 test_65j() { # bug6367
7642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7643
7644         sync; sleep 1
7645
7646         # if we aren't already remounting for each test, do so for this test
7647         if [ "$I_MOUNTED" = "yes" ]; then
7648                 cleanup || error "failed to unmount"
7649                 setup
7650         fi
7651
7652         save_layout_restore_at_exit $MOUNT
7653
7654         $LFS setstripe -d $MOUNT || error "setstripe failed"
7655 }
7656 run_test 65j "set default striping on root directory (bug 6367)="
7657
7658 cleanup_65k() {
7659         rm -rf $DIR/$tdir
7660         wait_delete_completed
7661         do_facet $SINGLEMDS "lctl set_param -n \
7662                 osp.$ost*MDT0000.max_create_count=$max_count"
7663         do_facet $SINGLEMDS "lctl set_param -n \
7664                 osp.$ost*MDT0000.create_count=$count"
7665         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7666         echo $INACTIVE_OSC "is Activate"
7667
7668         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7669 }
7670
7671 test_65k() { # bug11679
7672         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7673         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7674         remote_mds_nodsh && skip "remote MDS with nodsh"
7675
7676         local disable_precreate=true
7677         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7678                 disable_precreate=false
7679
7680         echo "Check OST status: "
7681         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7682                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7683
7684         for OSC in $MDS_OSCS; do
7685                 echo $OSC "is active"
7686                 do_facet $SINGLEMDS lctl --device %$OSC activate
7687         done
7688
7689         for INACTIVE_OSC in $MDS_OSCS; do
7690                 local ost=$(osc_to_ost $INACTIVE_OSC)
7691                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7692                                lov.*md*.target_obd |
7693                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7694
7695                 mkdir -p $DIR/$tdir
7696                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7697                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7698
7699                 echo "Deactivate: " $INACTIVE_OSC
7700                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7701
7702                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7703                               osp.$ost*MDT0000.create_count")
7704                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7705                                   osp.$ost*MDT0000.max_create_count")
7706                 $disable_precreate &&
7707                         do_facet $SINGLEMDS "lctl set_param -n \
7708                                 osp.$ost*MDT0000.max_create_count=0"
7709
7710                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7711                         [ -f $DIR/$tdir/$idx ] && continue
7712                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7713                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7714                                 { cleanup_65k;
7715                                   error "setstripe $idx should succeed"; }
7716                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7717                 done
7718                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7719                 rmdir $DIR/$tdir
7720
7721                 do_facet $SINGLEMDS "lctl set_param -n \
7722                         osp.$ost*MDT0000.max_create_count=$max_count"
7723                 do_facet $SINGLEMDS "lctl set_param -n \
7724                         osp.$ost*MDT0000.create_count=$count"
7725                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7726                 echo $INACTIVE_OSC "is Activate"
7727
7728                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7729         done
7730 }
7731 run_test 65k "validate manual striping works properly with deactivated OSCs"
7732
7733 test_65l() { # bug 12836
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735
7736         test_mkdir -p $DIR/$tdir/test_dir
7737         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7738         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7739 }
7740 run_test 65l "lfs find on -1 stripe dir ========================"
7741
7742 test_65m() {
7743         local layout=$(save_layout $MOUNT)
7744         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7745                 restore_layout $MOUNT $layout
7746                 error "setstripe should fail by non-root users"
7747         }
7748         true
7749 }
7750 run_test 65m "normal user can't set filesystem default stripe"
7751
7752 test_65n() {
7753         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7754         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7755                 skip "Need MDS version at least 2.12.50"
7756         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7757
7758         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7759         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7760         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7761
7762         local root_layout=$(save_layout $MOUNT)
7763         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7764
7765         # new subdirectory under root directory should not inherit
7766         # the default layout from root
7767         local dir1=$MOUNT/$tdir-1
7768         mkdir $dir1 || error "mkdir $dir1 failed"
7769         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7770                 error "$dir1 shouldn't have LOV EA"
7771
7772         # delete the default layout on root directory
7773         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7774
7775         local dir2=$MOUNT/$tdir-2
7776         mkdir $dir2 || error "mkdir $dir2 failed"
7777         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7778                 error "$dir2 shouldn't have LOV EA"
7779
7780         # set a new striping pattern on root directory
7781         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7782         local new_def_stripe_size=$((def_stripe_size * 2))
7783         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7784                 error "set stripe size on $MOUNT failed"
7785
7786         # new file created in $dir2 should inherit the new stripe size from
7787         # the filesystem default
7788         local file2=$dir2/$tfile-2
7789         touch $file2 || error "touch $file2 failed"
7790
7791         local file2_stripe_size=$($LFS getstripe -S $file2)
7792         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7793                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7794
7795         local dir3=$MOUNT/$tdir-3
7796         mkdir $dir3 || error "mkdir $dir3 failed"
7797         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7798                 error "$dir3 shouldn't have LOV EA"
7799
7800         # set OST pool on root directory
7801         local pool=$TESTNAME
7802         pool_add $pool || error "add $pool failed"
7803         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7804                 error "add targets to $pool failed"
7805
7806         $LFS setstripe -p $pool $MOUNT ||
7807                 error "set OST pool on $MOUNT failed"
7808
7809         # new file created in $dir3 should inherit the pool from
7810         # the filesystem default
7811         local file3=$dir3/$tfile-3
7812         touch $file3 || error "touch $file3 failed"
7813
7814         local file3_pool=$($LFS getstripe -p $file3)
7815         [[ "$file3_pool" = "$pool" ]] ||
7816                 error "$file3 didn't inherit OST pool $pool"
7817
7818         local dir4=$MOUNT/$tdir-4
7819         mkdir $dir4 || error "mkdir $dir4 failed"
7820         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7821                 error "$dir4 shouldn't have LOV EA"
7822
7823         # new file created in $dir4 should inherit the pool from
7824         # the filesystem default
7825         local file4=$dir4/$tfile-4
7826         touch $file4 || error "touch $file4 failed"
7827
7828         local file4_pool=$($LFS getstripe -p $file4)
7829         [[ "$file4_pool" = "$pool" ]] ||
7830                 error "$file4 didn't inherit OST pool $pool"
7831
7832         # new subdirectory under non-root directory should inherit
7833         # the default layout from its parent directory
7834         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7835                 error "set directory layout on $dir4 failed"
7836
7837         local dir5=$dir4/$tdir-5
7838         mkdir $dir5 || error "mkdir $dir5 failed"
7839
7840         local dir4_layout=$(get_layout_param $dir4)
7841         local dir5_layout=$(get_layout_param $dir5)
7842         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7843                 error "$dir5 should inherit the default layout from $dir4"
7844 }
7845 run_test 65n "don't inherit default layout from root for new subdirectories"
7846
7847 # bug 2543 - update blocks count on client
7848 test_66() {
7849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7850
7851         COUNT=${COUNT:-8}
7852         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7853         sync; sync_all_data; sync; sync_all_data
7854         cancel_lru_locks osc
7855         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7856         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7857 }
7858 run_test 66 "update inode blocks count on client ==============="
7859
7860 meminfo() {
7861         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7862 }
7863
7864 swap_used() {
7865         swapon -s | awk '($1 == "'$1'") { print $4 }'
7866 }
7867
7868 # bug5265, obdfilter oa2dentry return -ENOENT
7869 # #define OBD_FAIL_SRV_ENOENT 0x217
7870 test_69() {
7871         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7872         remote_ost_nodsh && skip "remote OST with nodsh"
7873
7874         f="$DIR/$tfile"
7875         $LFS setstripe -c 1 -i 0 $f
7876
7877         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7878
7879         do_facet ost1 lctl set_param fail_loc=0x217
7880         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7881         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7882
7883         do_facet ost1 lctl set_param fail_loc=0
7884         $DIRECTIO write $f 0 2 || error "write error"
7885
7886         cancel_lru_locks osc
7887         $DIRECTIO read $f 0 1 || error "read error"
7888
7889         do_facet ost1 lctl set_param fail_loc=0x217
7890         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7891
7892         do_facet ost1 lctl set_param fail_loc=0
7893         rm -f $f
7894 }
7895 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7896
7897 test_71() {
7898         test_mkdir $DIR/$tdir
7899         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7900         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7901 }
7902 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7903
7904 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7906         [ "$RUNAS_ID" = "$UID" ] &&
7907                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7908         # Check that testing environment is properly set up. Skip if not
7909         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7910                 skip_env "User $RUNAS_ID does not exist - skipping"
7911
7912         touch $DIR/$tfile
7913         chmod 777 $DIR/$tfile
7914         chmod ug+s $DIR/$tfile
7915         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7916                 error "$RUNAS dd $DIR/$tfile failed"
7917         # See if we are still setuid/sgid
7918         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7919                 error "S/gid is not dropped on write"
7920         # Now test that MDS is updated too
7921         cancel_lru_locks mdc
7922         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7923                 error "S/gid is not dropped on MDS"
7924         rm -f $DIR/$tfile
7925 }
7926 run_test 72a "Test that remove suid works properly (bug5695) ===="
7927
7928 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7929         local perm
7930
7931         [ "$RUNAS_ID" = "$UID" ] &&
7932                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7933         [ "$RUNAS_ID" -eq 0 ] &&
7934                 skip_env "RUNAS_ID = 0 -- skipping"
7935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7936         # Check that testing environment is properly set up. Skip if not
7937         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7938                 skip_env "User $RUNAS_ID does not exist - skipping"
7939
7940         touch $DIR/${tfile}-f{g,u}
7941         test_mkdir $DIR/${tfile}-dg
7942         test_mkdir $DIR/${tfile}-du
7943         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7944         chmod g+s $DIR/${tfile}-{f,d}g
7945         chmod u+s $DIR/${tfile}-{f,d}u
7946         for perm in 777 2777 4777; do
7947                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7948                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7949                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7950                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7951         done
7952         true
7953 }
7954 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7955
7956 # bug 3462 - multiple simultaneous MDC requests
7957 test_73() {
7958         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7959
7960         test_mkdir $DIR/d73-1
7961         test_mkdir $DIR/d73-2
7962         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7963         pid1=$!
7964
7965         lctl set_param fail_loc=0x80000129
7966         $MULTIOP $DIR/d73-1/f73-2 Oc &
7967         sleep 1
7968         lctl set_param fail_loc=0
7969
7970         $MULTIOP $DIR/d73-2/f73-3 Oc &
7971         pid3=$!
7972
7973         kill -USR1 $pid1
7974         wait $pid1 || return 1
7975
7976         sleep 25
7977
7978         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7979         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7980         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7981
7982         rm -rf $DIR/d73-*
7983 }
7984 run_test 73 "multiple MDC requests (should not deadlock)"
7985
7986 test_74a() { # bug 6149, 6184
7987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7988
7989         touch $DIR/f74a
7990         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7991         #
7992         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7993         # will spin in a tight reconnection loop
7994         $LCTL set_param fail_loc=0x8000030e
7995         # get any lock that won't be difficult - lookup works.
7996         ls $DIR/f74a
7997         $LCTL set_param fail_loc=0
7998         rm -f $DIR/f74a
7999         true
8000 }
8001 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
8002
8003 test_74b() { # bug 13310
8004         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8005
8006         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
8007         #
8008         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
8009         # will spin in a tight reconnection loop
8010         $LCTL set_param fail_loc=0x8000030e
8011         # get a "difficult" lock
8012         touch $DIR/f74b
8013         $LCTL set_param fail_loc=0
8014         rm -f $DIR/f74b
8015         true
8016 }
8017 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
8018
8019 test_74c() {
8020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8021
8022         #define OBD_FAIL_LDLM_NEW_LOCK
8023         $LCTL set_param fail_loc=0x319
8024         touch $DIR/$tfile && error "touch successful"
8025         $LCTL set_param fail_loc=0
8026         true
8027 }
8028 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
8029
8030 num_inodes() {
8031         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
8032 }
8033
8034 test_76() { # Now for bug 20433, added originally in bug 1443
8035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8036
8037         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
8038
8039         cancel_lru_locks osc
8040         BEFORE_INODES=$(num_inodes)
8041         echo "before inodes: $BEFORE_INODES"
8042         local COUNT=1000
8043         [ "$SLOW" = "no" ] && COUNT=100
8044         for i in $(seq $COUNT); do
8045                 touch $DIR/$tfile
8046                 rm -f $DIR/$tfile
8047         done
8048         cancel_lru_locks osc
8049         AFTER_INODES=$(num_inodes)
8050         echo "after inodes: $AFTER_INODES"
8051         local wait=0
8052         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
8053                 sleep 2
8054                 AFTER_INODES=$(num_inodes)
8055                 wait=$((wait+2))
8056                 echo "wait $wait seconds inodes: $AFTER_INODES"
8057                 if [ $wait -gt 30 ]; then
8058                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
8059                 fi
8060         done
8061 }
8062 run_test 76 "confirm clients recycle inodes properly ===="
8063
8064
8065 export ORIG_CSUM=""
8066 set_checksums()
8067 {
8068         # Note: in sptlrpc modes which enable its own bulk checksum, the
8069         # original crc32_le bulk checksum will be automatically disabled,
8070         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
8071         # will be checked by sptlrpc code against sptlrpc bulk checksum.
8072         # In this case set_checksums() will not be no-op, because sptlrpc
8073         # bulk checksum will be enabled all through the test.
8074
8075         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
8076         lctl set_param -n osc.*.checksums $1
8077         return 0
8078 }
8079
8080 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8081                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
8082 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
8083                              tr -d [] | head -n1)}
8084 set_checksum_type()
8085 {
8086         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
8087         rc=$?
8088         log "set checksum type to $1, rc = $rc"
8089         return $rc
8090 }
8091
8092 get_osc_checksum_type()
8093 {
8094         # arugment 1: OST name, like OST0000
8095         ost=$1
8096         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
8097                         sed 's/.*\[\(.*\)\].*/\1/g')
8098         rc=$?
8099         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
8100         echo $checksum_type
8101 }
8102
8103 F77_TMP=$TMP/f77-temp
8104 F77SZ=8
8105 setup_f77() {
8106         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
8107                 error "error writing to $F77_TMP"
8108 }
8109
8110 test_77a() { # bug 10889
8111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8112         $GSS && skip_env "could not run with gss"
8113
8114         [ ! -f $F77_TMP ] && setup_f77
8115         set_checksums 1
8116         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
8117         set_checksums 0
8118         rm -f $DIR/$tfile
8119 }
8120 run_test 77a "normal checksum read/write operation"
8121
8122 test_77b() { # bug 10889
8123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8124         $GSS && skip_env "could not run with gss"
8125
8126         [ ! -f $F77_TMP ] && setup_f77
8127         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8128         $LCTL set_param fail_loc=0x80000409
8129         set_checksums 1
8130
8131         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8132                 error "dd error: $?"
8133         $LCTL set_param fail_loc=0
8134
8135         for algo in $CKSUM_TYPES; do
8136                 cancel_lru_locks osc
8137                 set_checksum_type $algo
8138                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8139                 $LCTL set_param fail_loc=0x80000408
8140                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
8141                 $LCTL set_param fail_loc=0
8142         done
8143         set_checksums 0
8144         set_checksum_type $ORIG_CSUM_TYPE
8145         rm -f $DIR/$tfile
8146 }
8147 run_test 77b "checksum error on client write, read"
8148
8149 cleanup_77c() {
8150         trap 0
8151         set_checksums 0
8152         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
8153         $check_ost &&
8154                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
8155         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
8156         $check_ost && [ -n "$ost_file_prefix" ] &&
8157                 do_facet ost1 rm -f ${ost_file_prefix}\*
8158 }
8159
8160 test_77c() {
8161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8162         $GSS && skip_env "could not run with gss"
8163         remote_ost_nodsh && skip "remote OST with nodsh"
8164
8165         local bad1
8166         local osc_file_prefix
8167         local osc_file
8168         local check_ost=false
8169         local ost_file_prefix
8170         local ost_file
8171         local orig_cksum
8172         local dump_cksum
8173         local fid
8174
8175         # ensure corruption will occur on first OSS/OST
8176         $LFS setstripe -i 0 $DIR/$tfile
8177
8178         [ ! -f $F77_TMP ] && setup_f77
8179         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8180                 error "dd write error: $?"
8181         fid=$($LFS path2fid $DIR/$tfile)
8182
8183         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8184         then
8185                 check_ost=true
8186                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8187                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8188         else
8189                 echo "OSS do not support bulk pages dump upon error"
8190         fi
8191
8192         osc_file_prefix=$($LCTL get_param -n debug_path)
8193         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8194
8195         trap cleanup_77c EXIT
8196
8197         set_checksums 1
8198         # enable bulk pages dump upon error on Client
8199         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8200         # enable bulk pages dump upon error on OSS
8201         $check_ost &&
8202                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8203
8204         # flush Client cache to allow next read to reach OSS
8205         cancel_lru_locks osc
8206
8207         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8208         $LCTL set_param fail_loc=0x80000408
8209         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8210         $LCTL set_param fail_loc=0
8211
8212         rm -f $DIR/$tfile
8213
8214         # check cksum dump on Client
8215         osc_file=$(ls ${osc_file_prefix}*)
8216         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8217         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8218         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8219         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8220         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8221                      cksum)
8222         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8223         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8224                 error "dump content does not match on Client"
8225
8226         $check_ost || skip "No need to check cksum dump on OSS"
8227
8228         # check cksum dump on OSS
8229         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8230         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8231         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8232         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8233         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8234                 error "dump content does not match on OSS"
8235
8236         cleanup_77c
8237 }
8238 run_test 77c "checksum error on client read with debug"
8239
8240 test_77d() { # bug 10889
8241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8242         $GSS && skip_env "could not run with gss"
8243
8244         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8245         $LCTL set_param fail_loc=0x80000409
8246         set_checksums 1
8247         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8248                 error "direct write: rc=$?"
8249         $LCTL set_param fail_loc=0
8250         set_checksums 0
8251
8252         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8253         $LCTL set_param fail_loc=0x80000408
8254         set_checksums 1
8255         cancel_lru_locks osc
8256         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8257                 error "direct read: rc=$?"
8258         $LCTL set_param fail_loc=0
8259         set_checksums 0
8260 }
8261 run_test 77d "checksum error on OST direct write, read"
8262
8263 test_77f() { # bug 10889
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         $GSS && skip_env "could not run with gss"
8266
8267         set_checksums 1
8268         for algo in $CKSUM_TYPES; do
8269                 cancel_lru_locks osc
8270                 set_checksum_type $algo
8271                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8272                 $LCTL set_param fail_loc=0x409
8273                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8274                         error "direct write succeeded"
8275                 $LCTL set_param fail_loc=0
8276         done
8277         set_checksum_type $ORIG_CSUM_TYPE
8278         set_checksums 0
8279 }
8280 run_test 77f "repeat checksum error on write (expect error)"
8281
8282 test_77g() { # bug 10889
8283         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8284         $GSS && skip_env "could not run with gss"
8285         remote_ost_nodsh && skip "remote OST with nodsh"
8286
8287         [ ! -f $F77_TMP ] && setup_f77
8288
8289         local file=$DIR/$tfile
8290         stack_trap "rm -f $file" EXIT
8291
8292         $LFS setstripe -c 1 -i 0 $file
8293         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8294         do_facet ost1 lctl set_param fail_loc=0x8000021a
8295         set_checksums 1
8296         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8297                 error "write error: rc=$?"
8298         do_facet ost1 lctl set_param fail_loc=0
8299         set_checksums 0
8300
8301         cancel_lru_locks osc
8302         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8303         do_facet ost1 lctl set_param fail_loc=0x8000021b
8304         set_checksums 1
8305         cmp $F77_TMP $file || error "file compare failed"
8306         do_facet ost1 lctl set_param fail_loc=0
8307         set_checksums 0
8308 }
8309 run_test 77g "checksum error on OST write, read"
8310
8311 test_77k() { # LU-10906
8312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8313         $GSS && skip_env "could not run with gss"
8314
8315         local cksum_param="osc.$FSNAME*.checksums"
8316         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8317         local checksum
8318         local i
8319
8320         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8321         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8322         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8323                 EXIT
8324
8325         for i in 0 1; do
8326                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8327                         error "failed to set checksum=$i on MGS"
8328                 wait_update $HOSTNAME "$get_checksum" $i
8329                 #remount
8330                 echo "remount client, checksum should be $i"
8331                 remount_client $MOUNT || error "failed to remount client"
8332                 checksum=$(eval $get_checksum)
8333                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8334         done
8335         # remove persistent param to avoid races with checksum mountopt below
8336         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8337                 error "failed to delete checksum on MGS"
8338
8339         for opt in "checksum" "nochecksum"; do
8340                 #remount with mount option
8341                 echo "remount client with option $opt, checksum should be $i"
8342                 umount_client $MOUNT || error "failed to umount client"
8343                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8344                         error "failed to mount client with option '$opt'"
8345                 checksum=$(eval $get_checksum)
8346                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8347                 i=$((i - 1))
8348         done
8349
8350         remount_client $MOUNT || error "failed to remount client"
8351 }
8352 run_test 77k "enable/disable checksum correctly"
8353
8354 test_77l() {
8355         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8356         $GSS && skip_env "could not run with gss"
8357
8358         set_checksums 1
8359         stack_trap "set_checksums $ORIG_CSUM" EXIT
8360         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8361
8362         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8363
8364         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8365         for algo in $CKSUM_TYPES; do
8366                 set_checksum_type $algo || error "fail to set checksum type $algo"
8367                 osc_algo=$(get_osc_checksum_type OST0000)
8368                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8369
8370                 # no locks, no reqs to let the connection idle
8371                 cancel_lru_locks osc
8372                 lru_resize_disable osc
8373                 wait_osc_import_state client ost1 IDLE
8374
8375                 # ensure ost1 is connected
8376                 stat $DIR/$tfile >/dev/null || error "can't stat"
8377                 wait_osc_import_state client ost1 FULL
8378
8379                 osc_algo=$(get_osc_checksum_type OST0000)
8380                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8381         done
8382         return 0
8383 }
8384 run_test 77l "preferred checksum type is remembered after reconnected"
8385
8386 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8387 rm -f $F77_TMP
8388 unset F77_TMP
8389
8390 cleanup_test_78() {
8391         trap 0
8392         rm -f $DIR/$tfile
8393 }
8394
8395 test_78() { # bug 10901
8396         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8397         remote_ost || skip_env "local OST"
8398
8399         NSEQ=5
8400         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8401         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8402         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8403         echo "MemTotal: $MEMTOTAL"
8404
8405         # reserve 256MB of memory for the kernel and other running processes,
8406         # and then take 1/2 of the remaining memory for the read/write buffers.
8407         if [ $MEMTOTAL -gt 512 ] ;then
8408                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8409         else
8410                 # for those poor memory-starved high-end clusters...
8411                 MEMTOTAL=$((MEMTOTAL / 2))
8412         fi
8413         echo "Mem to use for directio: $MEMTOTAL"
8414
8415         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8416         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8417         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8418         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8419                 head -n1)
8420         echo "Smallest OST: $SMALLESTOST"
8421         [[ $SMALLESTOST -lt 10240 ]] &&
8422                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8423
8424         trap cleanup_test_78 EXIT
8425
8426         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8427                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8428
8429         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8430         echo "File size: $F78SIZE"
8431         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8432         for i in $(seq 1 $NSEQ); do
8433                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8434                 echo directIO rdwr round $i of $NSEQ
8435                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8436         done
8437
8438         cleanup_test_78
8439 }
8440 run_test 78 "handle large O_DIRECT writes correctly ============"
8441
8442 test_79() { # bug 12743
8443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8444
8445         wait_delete_completed
8446
8447         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8448         BKFREE=$(calc_osc_kbytes kbytesfree)
8449         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8450
8451         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8452         DFTOTAL=`echo $STRING | cut -d, -f1`
8453         DFUSED=`echo $STRING  | cut -d, -f2`
8454         DFAVAIL=`echo $STRING | cut -d, -f3`
8455         DFFREE=$(($DFTOTAL - $DFUSED))
8456
8457         ALLOWANCE=$((64 * $OSTCOUNT))
8458
8459         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8460            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8461                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8462         fi
8463         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8464            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8465                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8466         fi
8467         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8468            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8469                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8470         fi
8471 }
8472 run_test 79 "df report consistency check ======================="
8473
8474 test_80() { # bug 10718
8475         remote_ost_nodsh && skip "remote OST with nodsh"
8476         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8477
8478         # relax strong synchronous semantics for slow backends like ZFS
8479         local soc="obdfilter.*.sync_on_lock_cancel"
8480         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8481         local hosts=
8482         if [ "$soc_old" != "never" ] &&
8483                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8484                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8485                                 facet_active_host $host; done | sort -u)
8486                         do_nodes $hosts lctl set_param $soc=never
8487         fi
8488
8489         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8490         sync; sleep 1; sync
8491         local BEFORE=`date +%s`
8492         cancel_lru_locks osc
8493         local AFTER=`date +%s`
8494         local DIFF=$((AFTER-BEFORE))
8495         if [ $DIFF -gt 1 ] ; then
8496                 error "elapsed for 1M@1T = $DIFF"
8497         fi
8498
8499         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8500
8501         rm -f $DIR/$tfile
8502 }
8503 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8504
8505 test_81a() { # LU-456
8506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8507         remote_ost_nodsh && skip "remote OST with nodsh"
8508
8509         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8510         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8511         do_facet ost1 lctl set_param fail_loc=0x80000228
8512
8513         # write should trigger a retry and success
8514         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8515         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8516         RC=$?
8517         if [ $RC -ne 0 ] ; then
8518                 error "write should success, but failed for $RC"
8519         fi
8520 }
8521 run_test 81a "OST should retry write when get -ENOSPC ==============="
8522
8523 test_81b() { # LU-456
8524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8525         remote_ost_nodsh && skip "remote OST with nodsh"
8526
8527         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8528         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8529         do_facet ost1 lctl set_param fail_loc=0x228
8530
8531         # write should retry several times and return -ENOSPC finally
8532         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8533         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8534         RC=$?
8535         ENOSPC=28
8536         if [ $RC -ne $ENOSPC ] ; then
8537                 error "dd should fail for -ENOSPC, but succeed."
8538         fi
8539 }
8540 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8541
8542 test_82() { # LU-1031
8543         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8544         local gid1=14091995
8545         local gid2=16022000
8546
8547         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8548         local MULTIPID1=$!
8549         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8550         local MULTIPID2=$!
8551         kill -USR1 $MULTIPID2
8552         sleep 2
8553         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8554                 error "First grouplock does not block second one"
8555         else
8556                 echo "Second grouplock blocks first one"
8557         fi
8558         kill -USR1 $MULTIPID1
8559         wait $MULTIPID1
8560         wait $MULTIPID2
8561 }
8562 run_test 82 "Basic grouplock test"
8563
8564 test_99() {
8565         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8566
8567         test_mkdir $DIR/$tdir.cvsroot
8568         chown $RUNAS_ID $DIR/$tdir.cvsroot
8569
8570         cd $TMP
8571         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8572
8573         cd /etc/init.d
8574         # some versions of cvs import exit(1) when asked to import links or
8575         # files they can't read.  ignore those files.
8576         local toignore=$(find . -type l -printf '-I %f\n' -o \
8577                          ! -perm /4 -printf '-I %f\n')
8578         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8579                 $tdir.reposname vtag rtag
8580
8581         cd $DIR
8582         test_mkdir $DIR/$tdir.reposname
8583         chown $RUNAS_ID $DIR/$tdir.reposname
8584         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8585
8586         cd $DIR/$tdir.reposname
8587         $RUNAS touch foo99
8588         $RUNAS cvs add -m 'addmsg' foo99
8589         $RUNAS cvs update
8590         $RUNAS cvs commit -m 'nomsg' foo99
8591         rm -fr $DIR/$tdir.cvsroot
8592 }
8593 run_test 99 "cvs strange file/directory operations"
8594
8595 test_100() {
8596         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8597         [[ "$NETTYPE" =~ tcp ]] ||
8598                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8599         remote_ost_nodsh && skip "remote OST with nodsh"
8600         remote_mds_nodsh && skip "remote MDS with nodsh"
8601         remote_servers ||
8602                 skip "useless for local single node setup"
8603
8604         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8605                 [ "$PROT" != "tcp" ] && continue
8606                 RPORT=$(echo $REMOTE | cut -d: -f2)
8607                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8608
8609                 rc=0
8610                 LPORT=`echo $LOCAL | cut -d: -f2`
8611                 if [ $LPORT -ge 1024 ]; then
8612                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8613                         netstat -tna
8614                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8615                 fi
8616         done
8617         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8618 }
8619 run_test 100 "check local port using privileged port ==========="
8620
8621 function get_named_value()
8622 {
8623     local tag
8624
8625     tag=$1
8626     while read ;do
8627         line=$REPLY
8628         case $line in
8629         $tag*)
8630             echo $line | sed "s/^$tag[ ]*//"
8631             break
8632             ;;
8633         esac
8634     done
8635 }
8636
8637 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8638                    awk '/^max_cached_mb/ { print $2 }')
8639
8640 cleanup_101a() {
8641         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8642         trap 0
8643 }
8644
8645 test_101a() {
8646         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8647         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8648
8649         local s
8650         local discard
8651         local nreads=10000
8652         local cache_limit=32
8653
8654         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8655         trap cleanup_101a EXIT
8656         $LCTL set_param -n llite.*.read_ahead_stats 0
8657         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8658
8659         #
8660         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8661         #
8662         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8663         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8664
8665         discard=0
8666         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8667                 get_named_value 'read but discarded' | cut -d" " -f1); do
8668                         discard=$(($discard + $s))
8669         done
8670         cleanup_101a
8671
8672         if [[ $(($discard * 10)) -gt $nreads ]]; then
8673                 $LCTL get_param osc.*-osc*.rpc_stats
8674                 $LCTL get_param llite.*.read_ahead_stats
8675                 error "too many ($discard) discarded pages"
8676         fi
8677         rm -f $DIR/$tfile || true
8678 }
8679 run_test 101a "check read-ahead for random reads"
8680
8681 setup_test101bc() {
8682         test_mkdir $DIR/$tdir
8683         local ssize=$1
8684         local FILE_LENGTH=$2
8685         STRIPE_OFFSET=0
8686
8687         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8688
8689         local list=$(comma_list $(osts_nodes))
8690         set_osd_param $list '' read_cache_enable 0
8691         set_osd_param $list '' writethrough_cache_enable 0
8692
8693         trap cleanup_test101bc EXIT
8694         # prepare the read-ahead file
8695         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8696
8697         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8698                                 count=$FILE_SIZE_MB 2> /dev/null
8699
8700 }
8701
8702 cleanup_test101bc() {
8703         trap 0
8704         rm -rf $DIR/$tdir
8705         rm -f $DIR/$tfile
8706
8707         local list=$(comma_list $(osts_nodes))
8708         set_osd_param $list '' read_cache_enable 1
8709         set_osd_param $list '' writethrough_cache_enable 1
8710 }
8711
8712 calc_total() {
8713         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8714 }
8715
8716 ra_check_101() {
8717         local READ_SIZE=$1
8718         local STRIPE_SIZE=$2
8719         local FILE_LENGTH=$3
8720         local RA_INC=1048576
8721         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8722         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8723                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8724         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8725                         get_named_value 'read but discarded' |
8726                         cut -d" " -f1 | calc_total)
8727         if [[ $DISCARD -gt $discard_limit ]]; then
8728                 $LCTL get_param llite.*.read_ahead_stats
8729                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8730         else
8731                 echo "Read-ahead success for size ${READ_SIZE}"
8732         fi
8733 }
8734
8735 test_101b() {
8736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8737         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8738
8739         local STRIPE_SIZE=1048576
8740         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8741
8742         if [ $SLOW == "yes" ]; then
8743                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8744         else
8745                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8746         fi
8747
8748         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8749
8750         # prepare the read-ahead file
8751         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8752         cancel_lru_locks osc
8753         for BIDX in 2 4 8 16 32 64 128 256
8754         do
8755                 local BSIZE=$((BIDX*4096))
8756                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8757                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8758                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8759                 $LCTL set_param -n llite.*.read_ahead_stats 0
8760                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8761                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8762                 cancel_lru_locks osc
8763                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8764         done
8765         cleanup_test101bc
8766         true
8767 }
8768 run_test 101b "check stride-io mode read-ahead ================="
8769
8770 test_101c() {
8771         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8772
8773         local STRIPE_SIZE=1048576
8774         local FILE_LENGTH=$((STRIPE_SIZE*100))
8775         local nreads=10000
8776         local rsize=65536
8777         local osc_rpc_stats
8778
8779         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8780
8781         cancel_lru_locks osc
8782         $LCTL set_param osc.*.rpc_stats 0
8783         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8784         $LCTL get_param osc.*.rpc_stats
8785         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8786                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8787                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8788                 local size
8789
8790                 if [ $lines -le 20 ]; then
8791                         echo "continue debug"
8792                         continue
8793                 fi
8794                 for size in 1 2 4 8; do
8795                         local rpc=$(echo "$stats" |
8796                                     awk '($1 == "'$size':") {print $2; exit; }')
8797                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8798                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8799                 done
8800                 echo "$osc_rpc_stats check passed!"
8801         done
8802         cleanup_test101bc
8803         true
8804 }
8805 run_test 101c "check stripe_size aligned read-ahead ================="
8806
8807 set_read_ahead() {
8808         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8809         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8810 }
8811
8812 test_101d() {
8813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8814
8815         local file=$DIR/$tfile
8816         local sz_MB=${FILESIZE_101d:-500}
8817         local ra_MB=${READAHEAD_MB:-40}
8818
8819         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8820         [ $free_MB -lt $sz_MB ] &&
8821                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8822
8823         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8824         $LFS setstripe -c -1 $file || error "setstripe failed"
8825
8826         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8827         echo Cancel LRU locks on lustre client to flush the client cache
8828         cancel_lru_locks osc
8829
8830         echo Disable read-ahead
8831         local old_READAHEAD=$(set_read_ahead 0)
8832
8833         echo Reading the test file $file with read-ahead disabled
8834         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8835
8836         echo Cancel LRU locks on lustre client to flush the client cache
8837         cancel_lru_locks osc
8838         echo Enable read-ahead with ${ra_MB}MB
8839         set_read_ahead $ra_MB
8840
8841         echo Reading the test file $file with read-ahead enabled
8842         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8843
8844         echo "read-ahead disabled time read $raOFF"
8845         echo "read-ahead enabled  time read $raON"
8846
8847         set_read_ahead $old_READAHEAD
8848         rm -f $file
8849         wait_delete_completed
8850
8851         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8852                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8853 }
8854 run_test 101d "file read with and without read-ahead enabled"
8855
8856 test_101e() {
8857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8858
8859         local file=$DIR/$tfile
8860         local size_KB=500  #KB
8861         local count=100
8862         local bsize=1024
8863
8864         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8865         local need_KB=$((count * size_KB))
8866         [[ $free_KB -le $need_KB ]] &&
8867                 skip_env "Need free space $need_KB, have $free_KB"
8868
8869         echo "Creating $count ${size_KB}K test files"
8870         for ((i = 0; i < $count; i++)); do
8871                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8872         done
8873
8874         echo "Cancel LRU locks on lustre client to flush the client cache"
8875         cancel_lru_locks $OSC
8876
8877         echo "Reset readahead stats"
8878         $LCTL set_param -n llite.*.read_ahead_stats 0
8879
8880         for ((i = 0; i < $count; i++)); do
8881                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8882         done
8883
8884         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8885                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8886
8887         for ((i = 0; i < $count; i++)); do
8888                 rm -rf $file.$i 2>/dev/null
8889         done
8890
8891         #10000 means 20% reads are missing in readahead
8892         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8893 }
8894 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8895
8896 test_101f() {
8897         which iozone || skip_env "no iozone installed"
8898
8899         local old_debug=$($LCTL get_param debug)
8900         old_debug=${old_debug#*=}
8901         $LCTL set_param debug="reada mmap"
8902
8903         # create a test file
8904         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8905
8906         echo Cancel LRU locks on lustre client to flush the client cache
8907         cancel_lru_locks osc
8908
8909         echo Reset readahead stats
8910         $LCTL set_param -n llite.*.read_ahead_stats 0
8911
8912         echo mmap read the file with small block size
8913         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8914                 > /dev/null 2>&1
8915
8916         echo checking missing pages
8917         $LCTL get_param llite.*.read_ahead_stats
8918         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8919                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8920
8921         $LCTL set_param debug="$old_debug"
8922         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8923         rm -f $DIR/$tfile
8924 }
8925 run_test 101f "check mmap read performance"
8926
8927 test_101g_brw_size_test() {
8928         local mb=$1
8929         local pages=$((mb * 1048576 / PAGE_SIZE))
8930         local file=$DIR/$tfile
8931
8932         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8933                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8934         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8935                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8936                         return 2
8937         done
8938
8939         stack_trap "rm -f $file" EXIT
8940         $LCTL set_param -n osc.*.rpc_stats=0
8941
8942         # 10 RPCs should be enough for the test
8943         local count=10
8944         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8945                 { error "dd write ${mb} MB blocks failed"; return 3; }
8946         cancel_lru_locks osc
8947         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8948                 { error "dd write ${mb} MB blocks failed"; return 4; }
8949
8950         # calculate number of full-sized read and write RPCs
8951         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8952                 sed -n '/pages per rpc/,/^$/p' |
8953                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8954                 END { print reads,writes }'))
8955         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8956                 return 5
8957         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8958                 return 6
8959
8960         return 0
8961 }
8962
8963 test_101g() {
8964         remote_ost_nodsh && skip "remote OST with nodsh"
8965
8966         local rpcs
8967         local osts=$(get_facets OST)
8968         local list=$(comma_list $(osts_nodes))
8969         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8970         local brw_size="obdfilter.*.brw_size"
8971
8972         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8973
8974         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8975
8976         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8977                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8978                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8979            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8980                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8981                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8982
8983                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8984                         suffix="M"
8985
8986                 if [[ $orig_mb -lt 16 ]]; then
8987                         save_lustre_params $osts "$brw_size" > $p
8988                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8989                                 error "set 16MB RPC size failed"
8990
8991                         echo "remount client to enable new RPC size"
8992                         remount_client $MOUNT || error "remount_client failed"
8993                 fi
8994
8995                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8996                 # should be able to set brw_size=12, but no rpc_stats for that
8997                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8998         fi
8999
9000         test_101g_brw_size_test 4 || error "4MB RPC test failed"
9001
9002         if [[ $orig_mb -lt 16 ]]; then
9003                 restore_lustre_params < $p
9004                 remount_client $MOUNT || error "remount_client restore failed"
9005         fi
9006
9007         rm -f $p $DIR/$tfile
9008 }
9009 run_test 101g "Big bulk(4/16 MiB) readahead"
9010
9011 test_101h() {
9012         $LFS setstripe -i 0 -c 1 $DIR/$tfile
9013
9014         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
9015                 error "dd 70M file failed"
9016         echo Cancel LRU locks on lustre client to flush the client cache
9017         cancel_lru_locks osc
9018
9019         echo "Reset readahead stats"
9020         $LCTL set_param -n llite.*.read_ahead_stats 0
9021
9022         echo "Read 10M of data but cross 64M bundary"
9023         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
9024         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
9025                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
9026         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
9027         rm -f $p $DIR/$tfile
9028 }
9029 run_test 101h "Readahead should cover current read window"
9030
9031 setup_test102() {
9032         test_mkdir $DIR/$tdir
9033         chown $RUNAS_ID $DIR/$tdir
9034         STRIPE_SIZE=65536
9035         STRIPE_OFFSET=1
9036         STRIPE_COUNT=$OSTCOUNT
9037         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
9038
9039         trap cleanup_test102 EXIT
9040         cd $DIR
9041         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
9042         cd $DIR/$tdir
9043         for num in 1 2 3 4; do
9044                 for count in $(seq 1 $STRIPE_COUNT); do
9045                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
9046                                 local size=`expr $STRIPE_SIZE \* $num`
9047                                 local file=file"$num-$idx-$count"
9048                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
9049                         done
9050                 done
9051         done
9052
9053         cd $DIR
9054         $1 tar cf $TMP/f102.tar $tdir --xattrs
9055 }
9056
9057 cleanup_test102() {
9058         trap 0
9059         rm -f $TMP/f102.tar
9060         rm -rf $DIR/d0.sanity/d102
9061 }
9062
9063 test_102a() {
9064         [ "$UID" != 0 ] && skip "must run as root"
9065         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
9066                 skip_env "must have user_xattr"
9067
9068         [ -z "$(which setfattr 2>/dev/null)" ] &&
9069                 skip_env "could not find setfattr"
9070
9071         local testfile=$DIR/$tfile
9072
9073         touch $testfile
9074         echo "set/get xattr..."
9075         setfattr -n trusted.name1 -v value1 $testfile ||
9076                 error "setfattr -n trusted.name1=value1 $testfile failed"
9077         getfattr -n trusted.name1 $testfile 2> /dev/null |
9078           grep "trusted.name1=.value1" ||
9079                 error "$testfile missing trusted.name1=value1"
9080
9081         setfattr -n user.author1 -v author1 $testfile ||
9082                 error "setfattr -n user.author1=author1 $testfile failed"
9083         getfattr -n user.author1 $testfile 2> /dev/null |
9084           grep "user.author1=.author1" ||
9085                 error "$testfile missing trusted.author1=author1"
9086
9087         echo "listxattr..."
9088         setfattr -n trusted.name2 -v value2 $testfile ||
9089                 error "$testfile unable to set trusted.name2"
9090         setfattr -n trusted.name3 -v value3 $testfile ||
9091                 error "$testfile unable to set trusted.name3"
9092         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
9093             grep "trusted.name" | wc -l) -eq 3 ] ||
9094                 error "$testfile missing 3 trusted.name xattrs"
9095
9096         setfattr -n user.author2 -v author2 $testfile ||
9097                 error "$testfile unable to set user.author2"
9098         setfattr -n user.author3 -v author3 $testfile ||
9099                 error "$testfile unable to set user.author3"
9100         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
9101             grep "user.author" | wc -l) -eq 3 ] ||
9102                 error "$testfile missing 3 user.author xattrs"
9103
9104         echo "remove xattr..."
9105         setfattr -x trusted.name1 $testfile ||
9106                 error "$testfile error deleting trusted.name1"
9107         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
9108                 error "$testfile did not delete trusted.name1 xattr"
9109
9110         setfattr -x user.author1 $testfile ||
9111                 error "$testfile error deleting user.author1"
9112         echo "set lustre special xattr ..."
9113         $LFS setstripe -c1 $testfile
9114         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
9115                 awk -F "=" '/trusted.lov/ { print $2 }' )
9116         setfattr -n "trusted.lov" -v $lovea $testfile ||
9117                 error "$testfile doesn't ignore setting trusted.lov again"
9118         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
9119                 error "$testfile allow setting invalid trusted.lov"
9120         rm -f $testfile
9121 }
9122 run_test 102a "user xattr test =================================="
9123
9124 test_102b() {
9125         [ -z "$(which setfattr 2>/dev/null)" ] &&
9126                 skip_env "could not find setfattr"
9127         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9128
9129         # b10930: get/set/list trusted.lov xattr
9130         echo "get/set/list trusted.lov xattr ..."
9131         local testfile=$DIR/$tfile
9132         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9133                 error "setstripe failed"
9134         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
9135                 error "getstripe failed"
9136         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
9137                 error "can't get trusted.lov from $testfile"
9138
9139         local testfile2=${testfile}2
9140         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
9141                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
9142
9143         $MCREATE $testfile2
9144         setfattr -n trusted.lov -v $value $testfile2
9145         local stripe_size=$($LFS getstripe -S $testfile2)
9146         local stripe_count=$($LFS getstripe -c $testfile2)
9147         [[ $stripe_size -eq 65536 ]] ||
9148                 error "stripe size $stripe_size != 65536"
9149         [[ $stripe_count -eq $STRIPECOUNT ]] ||
9150                 error "stripe count $stripe_count != $STRIPECOUNT"
9151         rm -f $DIR/$tfile
9152 }
9153 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
9154
9155 test_102c() {
9156         [ -z "$(which setfattr 2>/dev/null)" ] &&
9157                 skip_env "could not find setfattr"
9158         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9159
9160         # b10930: get/set/list lustre.lov xattr
9161         echo "get/set/list lustre.lov xattr ..."
9162         test_mkdir $DIR/$tdir
9163         chown $RUNAS_ID $DIR/$tdir
9164         local testfile=$DIR/$tdir/$tfile
9165         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
9166                 error "setstripe failed"
9167         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
9168                 error "getstripe failed"
9169         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
9170         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
9171
9172         local testfile2=${testfile}2
9173         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
9174                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
9175
9176         $RUNAS $MCREATE $testfile2
9177         $RUNAS setfattr -n lustre.lov -v $value $testfile2
9178         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
9179         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9180         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9181         [ $stripe_count -eq $STRIPECOUNT ] ||
9182                 error "stripe count $stripe_count != $STRIPECOUNT"
9183 }
9184 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9185
9186 compare_stripe_info1() {
9187         local stripe_index_all_zero=true
9188
9189         for num in 1 2 3 4; do
9190                 for count in $(seq 1 $STRIPE_COUNT); do
9191                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9192                                 local size=$((STRIPE_SIZE * num))
9193                                 local file=file"$num-$offset-$count"
9194                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9195                                 [[ $stripe_size -ne $size ]] &&
9196                                     error "$file: size $stripe_size != $size"
9197                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9198                                 # allow fewer stripes to be created, ORI-601
9199                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9200                                     error "$file: count $stripe_count != $count"
9201                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9202                                 [[ $stripe_index -ne 0 ]] &&
9203                                         stripe_index_all_zero=false
9204                         done
9205                 done
9206         done
9207         $stripe_index_all_zero &&
9208                 error "all files are being extracted starting from OST index 0"
9209         return 0
9210 }
9211
9212 have_xattrs_include() {
9213         tar --help | grep -q xattrs-include &&
9214                 echo --xattrs-include="lustre.*"
9215 }
9216
9217 test_102d() {
9218         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9219         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9220
9221         XINC=$(have_xattrs_include)
9222         setup_test102
9223         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9224         cd $DIR/$tdir/$tdir
9225         compare_stripe_info1
9226 }
9227 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9228
9229 test_102f() {
9230         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9231         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9232
9233         XINC=$(have_xattrs_include)
9234         setup_test102
9235         test_mkdir $DIR/$tdir.restore
9236         cd $DIR
9237         tar cf - --xattrs $tdir | tar xf - \
9238                 -C $DIR/$tdir.restore --xattrs $XINC
9239         cd $DIR/$tdir.restore/$tdir
9240         compare_stripe_info1
9241 }
9242 run_test 102f "tar copy files, not keep osts"
9243
9244 grow_xattr() {
9245         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9246                 skip "must have user_xattr"
9247         [ -z "$(which setfattr 2>/dev/null)" ] &&
9248                 skip_env "could not find setfattr"
9249         [ -z "$(which getfattr 2>/dev/null)" ] &&
9250                 skip_env "could not find getfattr"
9251
9252         local xsize=${1:-1024}  # in bytes
9253         local file=$DIR/$tfile
9254         local value="$(generate_string $xsize)"
9255         local xbig=trusted.big
9256         local toobig=$2
9257
9258         touch $file
9259         log "save $xbig on $file"
9260         if [ -z "$toobig" ]
9261         then
9262                 setfattr -n $xbig -v $value $file ||
9263                         error "saving $xbig on $file failed"
9264         else
9265                 setfattr -n $xbig -v $value $file &&
9266                         error "saving $xbig on $file succeeded"
9267                 return 0
9268         fi
9269
9270         local orig=$(get_xattr_value $xbig $file)
9271         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9272
9273         local xsml=trusted.sml
9274         log "save $xsml on $file"
9275         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9276
9277         local new=$(get_xattr_value $xbig $file)
9278         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9279
9280         log "grow $xsml on $file"
9281         setfattr -n $xsml -v "$value" $file ||
9282                 error "growing $xsml on $file failed"
9283
9284         new=$(get_xattr_value $xbig $file)
9285         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9286         log "$xbig still valid after growing $xsml"
9287
9288         rm -f $file
9289 }
9290
9291 test_102h() { # bug 15777
9292         grow_xattr 1024
9293 }
9294 run_test 102h "grow xattr from inside inode to external block"
9295
9296 test_102ha() {
9297         large_xattr_enabled || skip_env "ea_inode feature disabled"
9298
9299         echo "setting xattr of max xattr size: $(max_xattr_size)"
9300         grow_xattr $(max_xattr_size)
9301
9302         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9303         echo "This should fail:"
9304         grow_xattr $(($(max_xattr_size) + 10)) 1
9305 }
9306 run_test 102ha "grow xattr from inside inode to external inode"
9307
9308 test_102i() { # bug 17038
9309         [ -z "$(which getfattr 2>/dev/null)" ] &&
9310                 skip "could not find getfattr"
9311
9312         touch $DIR/$tfile
9313         ln -s $DIR/$tfile $DIR/${tfile}link
9314         getfattr -n trusted.lov $DIR/$tfile ||
9315                 error "lgetxattr on $DIR/$tfile failed"
9316         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9317                 grep -i "no such attr" ||
9318                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9319         rm -f $DIR/$tfile $DIR/${tfile}link
9320 }
9321 run_test 102i "lgetxattr test on symbolic link ============"
9322
9323 test_102j() {
9324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9325         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9326
9327         XINC=$(have_xattrs_include)
9328         setup_test102 "$RUNAS"
9329         chown $RUNAS_ID $DIR/$tdir
9330         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9331         cd $DIR/$tdir/$tdir
9332         compare_stripe_info1 "$RUNAS"
9333 }
9334 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9335
9336 test_102k() {
9337         [ -z "$(which setfattr 2>/dev/null)" ] &&
9338                 skip "could not find setfattr"
9339
9340         touch $DIR/$tfile
9341         # b22187 just check that does not crash for regular file.
9342         setfattr -n trusted.lov $DIR/$tfile
9343         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9344         local test_kdir=$DIR/$tdir
9345         test_mkdir $test_kdir
9346         local default_size=$($LFS getstripe -S $test_kdir)
9347         local default_count=$($LFS getstripe -c $test_kdir)
9348         local default_offset=$($LFS getstripe -i $test_kdir)
9349         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9350                 error 'dir setstripe failed'
9351         setfattr -n trusted.lov $test_kdir
9352         local stripe_size=$($LFS getstripe -S $test_kdir)
9353         local stripe_count=$($LFS getstripe -c $test_kdir)
9354         local stripe_offset=$($LFS getstripe -i $test_kdir)
9355         [ $stripe_size -eq $default_size ] ||
9356                 error "stripe size $stripe_size != $default_size"
9357         [ $stripe_count -eq $default_count ] ||
9358                 error "stripe count $stripe_count != $default_count"
9359         [ $stripe_offset -eq $default_offset ] ||
9360                 error "stripe offset $stripe_offset != $default_offset"
9361         rm -rf $DIR/$tfile $test_kdir
9362 }
9363 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9364
9365 test_102l() {
9366         [ -z "$(which getfattr 2>/dev/null)" ] &&
9367                 skip "could not find getfattr"
9368
9369         # LU-532 trusted. xattr is invisible to non-root
9370         local testfile=$DIR/$tfile
9371
9372         touch $testfile
9373
9374         echo "listxattr as user..."
9375         chown $RUNAS_ID $testfile
9376         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9377             grep -q "trusted" &&
9378                 error "$testfile trusted xattrs are user visible"
9379
9380         return 0;
9381 }
9382 run_test 102l "listxattr size test =================================="
9383
9384 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9385         local path=$DIR/$tfile
9386         touch $path
9387
9388         listxattr_size_check $path || error "listattr_size_check $path failed"
9389 }
9390 run_test 102m "Ensure listxattr fails on small bufffer ========"
9391
9392 cleanup_test102
9393
9394 getxattr() { # getxattr path name
9395         # Return the base64 encoding of the value of xattr name on path.
9396         local path=$1
9397         local name=$2
9398
9399         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9400         # file: $path
9401         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9402         #
9403         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9404
9405         getfattr --absolute-names --encoding=base64 --name=$name $path |
9406                 awk -F= -v name=$name '$1 == name {
9407                         print substr($0, index($0, "=") + 1);
9408         }'
9409 }
9410
9411 test_102n() { # LU-4101 mdt: protect internal xattrs
9412         [ -z "$(which setfattr 2>/dev/null)" ] &&
9413                 skip "could not find setfattr"
9414         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9415         then
9416                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9417         fi
9418
9419         local file0=$DIR/$tfile.0
9420         local file1=$DIR/$tfile.1
9421         local xattr0=$TMP/$tfile.0
9422         local xattr1=$TMP/$tfile.1
9423         local namelist="lov lma lmv link fid version som hsm"
9424         local name
9425         local value
9426
9427         rm -rf $file0 $file1 $xattr0 $xattr1
9428         touch $file0 $file1
9429
9430         # Get 'before' xattrs of $file1.
9431         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9432
9433         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9434                 namelist+=" lfsck_namespace"
9435         for name in $namelist; do
9436                 # Try to copy xattr from $file0 to $file1.
9437                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9438
9439                 setfattr --name=trusted.$name --value="$value" $file1 ||
9440                         error "setxattr 'trusted.$name' failed"
9441
9442                 # Try to set a garbage xattr.
9443                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9444
9445                 if [[ x$name == "xlov" ]]; then
9446                         setfattr --name=trusted.lov --value="$value" $file1 &&
9447                         error "setxattr invalid 'trusted.lov' success"
9448                 else
9449                         setfattr --name=trusted.$name --value="$value" $file1 ||
9450                                 error "setxattr invalid 'trusted.$name' failed"
9451                 fi
9452
9453                 # Try to remove the xattr from $file1. We don't care if this
9454                 # appears to succeed or fail, we just don't want there to be
9455                 # any changes or crashes.
9456                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9457         done
9458
9459         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9460         then
9461                 name="lfsck_ns"
9462                 # Try to copy xattr from $file0 to $file1.
9463                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9464
9465                 setfattr --name=trusted.$name --value="$value" $file1 ||
9466                         error "setxattr 'trusted.$name' failed"
9467
9468                 # Try to set a garbage xattr.
9469                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9470
9471                 setfattr --name=trusted.$name --value="$value" $file1 ||
9472                         error "setxattr 'trusted.$name' failed"
9473
9474                 # Try to remove the xattr from $file1. We don't care if this
9475                 # appears to succeed or fail, we just don't want there to be
9476                 # any changes or crashes.
9477                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9478         fi
9479
9480         # Get 'after' xattrs of file1.
9481         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9482
9483         if ! diff $xattr0 $xattr1; then
9484                 error "before and after xattrs of '$file1' differ"
9485         fi
9486
9487         rm -rf $file0 $file1 $xattr0 $xattr1
9488
9489         return 0
9490 }
9491 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9492
9493 test_102p() { # LU-4703 setxattr did not check ownership
9494         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9495                 skip "MDS needs to be at least 2.5.56"
9496
9497         local testfile=$DIR/$tfile
9498
9499         touch $testfile
9500
9501         echo "setfacl as user..."
9502         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9503         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9504
9505         echo "setfattr as user..."
9506         setfacl -m "u:$RUNAS_ID:---" $testfile
9507         $RUNAS setfattr -x system.posix_acl_access $testfile
9508         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9509 }
9510 run_test 102p "check setxattr(2) correctly fails without permission"
9511
9512 test_102q() {
9513         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9514                 skip "MDS needs to be at least 2.6.92"
9515
9516         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9517 }
9518 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9519
9520 test_102r() {
9521         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9522                 skip "MDS needs to be at least 2.6.93"
9523
9524         touch $DIR/$tfile || error "touch"
9525         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9526         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9527         rm $DIR/$tfile || error "rm"
9528
9529         #normal directory
9530         mkdir -p $DIR/$tdir || error "mkdir"
9531         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9532         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9533         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9534                 error "$testfile error deleting user.author1"
9535         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9536                 grep "user.$(basename $tdir)" &&
9537                 error "$tdir did not delete user.$(basename $tdir)"
9538         rmdir $DIR/$tdir || error "rmdir"
9539
9540         #striped directory
9541         test_mkdir $DIR/$tdir
9542         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9543         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9544         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9545                 error "$testfile error deleting user.author1"
9546         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9547                 grep "user.$(basename $tdir)" &&
9548                 error "$tdir did not delete user.$(basename $tdir)"
9549         rmdir $DIR/$tdir || error "rm striped dir"
9550 }
9551 run_test 102r "set EAs with empty values"
9552
9553 test_102s() {
9554         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9555                 skip "MDS needs to be at least 2.11.52"
9556
9557         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9558
9559         save_lustre_params client "llite.*.xattr_cache" > $save
9560
9561         for cache in 0 1; do
9562                 lctl set_param llite.*.xattr_cache=$cache
9563
9564                 rm -f $DIR/$tfile
9565                 touch $DIR/$tfile || error "touch"
9566                 for prefix in lustre security system trusted user; do
9567                         # Note getxattr() may fail with 'Operation not
9568                         # supported' or 'No such attribute' depending
9569                         # on prefix and cache.
9570                         getfattr -n $prefix.n102s $DIR/$tfile &&
9571                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9572                 done
9573         done
9574
9575         restore_lustre_params < $save
9576 }
9577 run_test 102s "getting nonexistent xattrs should fail"
9578
9579 test_102t() {
9580         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9581                 skip "MDS needs to be at least 2.11.52"
9582
9583         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9584
9585         save_lustre_params client "llite.*.xattr_cache" > $save
9586
9587         for cache in 0 1; do
9588                 lctl set_param llite.*.xattr_cache=$cache
9589
9590                 for buf_size in 0 256; do
9591                         rm -f $DIR/$tfile
9592                         touch $DIR/$tfile || error "touch"
9593                         setfattr -n user.multiop $DIR/$tfile
9594                         $MULTIOP $DIR/$tfile oa$buf_size ||
9595                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9596                 done
9597         done
9598
9599         restore_lustre_params < $save
9600 }
9601 run_test 102t "zero length xattr values handled correctly"
9602
9603 run_acl_subtest()
9604 {
9605     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9606     return $?
9607 }
9608
9609 test_103a() {
9610         [ "$UID" != 0 ] && skip "must run as root"
9611         $GSS && skip_env "could not run under gss"
9612         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9613                 skip_env "must have acl enabled"
9614         [ -z "$(which setfacl 2>/dev/null)" ] &&
9615                 skip_env "could not find setfacl"
9616         remote_mds_nodsh && skip "remote MDS with nodsh"
9617
9618         gpasswd -a daemon bin                           # LU-5641
9619         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9620
9621         declare -a identity_old
9622
9623         for num in $(seq $MDSCOUNT); do
9624                 switch_identity $num true || identity_old[$num]=$?
9625         done
9626
9627         SAVE_UMASK=$(umask)
9628         umask 0022
9629         mkdir -p $DIR/$tdir
9630         cd $DIR/$tdir
9631
9632         echo "performing cp ..."
9633         run_acl_subtest cp || error "run_acl_subtest cp failed"
9634         echo "performing getfacl-noacl..."
9635         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9636         echo "performing misc..."
9637         run_acl_subtest misc || error  "misc test failed"
9638         echo "performing permissions..."
9639         run_acl_subtest permissions || error "permissions failed"
9640         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9641         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9642                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9643                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9644         then
9645                 echo "performing permissions xattr..."
9646                 run_acl_subtest permissions_xattr ||
9647                         error "permissions_xattr failed"
9648         fi
9649         echo "performing setfacl..."
9650         run_acl_subtest setfacl || error  "setfacl test failed"
9651
9652         # inheritance test got from HP
9653         echo "performing inheritance..."
9654         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9655         chmod +x make-tree || error "chmod +x failed"
9656         run_acl_subtest inheritance || error "inheritance test failed"
9657         rm -f make-tree
9658
9659         echo "LU-974 ignore umask when acl is enabled..."
9660         run_acl_subtest 974 || error "LU-974 umask test failed"
9661         if [ $MDSCOUNT -ge 2 ]; then
9662                 run_acl_subtest 974_remote ||
9663                         error "LU-974 umask test failed under remote dir"
9664         fi
9665
9666         echo "LU-2561 newly created file is same size as directory..."
9667         if [ "$mds1_FSTYPE" != "zfs" ]; then
9668                 run_acl_subtest 2561 || error "LU-2561 test failed"
9669         else
9670                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9671         fi
9672
9673         run_acl_subtest 4924 || error "LU-4924 test failed"
9674
9675         cd $SAVE_PWD
9676         umask $SAVE_UMASK
9677
9678         for num in $(seq $MDSCOUNT); do
9679                 if [ "${identity_old[$num]}" = 1 ]; then
9680                         switch_identity $num false || identity_old[$num]=$?
9681                 fi
9682         done
9683 }
9684 run_test 103a "acl test"
9685
9686 test_103b() {
9687         declare -a pids
9688         local U
9689
9690         for U in {0..511}; do
9691                 {
9692                 local O=$(printf "%04o" $U)
9693
9694                 umask $(printf "%04o" $((511 ^ $O)))
9695                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9696                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9697
9698                 (( $S == ($O & 0666) )) ||
9699                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9700
9701                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9702                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9703                 (( $S == ($O & 0666) )) ||
9704                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9705
9706                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9707                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9708                 (( $S == ($O & 0666) )) ||
9709                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9710                 rm -f $DIR/$tfile.[smp]$0
9711                 } &
9712                 local pid=$!
9713
9714                 # limit the concurrently running threads to 64. LU-11878
9715                 local idx=$((U % 64))
9716                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9717                 pids[idx]=$pid
9718         done
9719         wait
9720 }
9721 run_test 103b "umask lfs setstripe"
9722
9723 test_103c() {
9724         mkdir -p $DIR/$tdir
9725         cp -rp $DIR/$tdir $DIR/$tdir.bak
9726
9727         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9728                 error "$DIR/$tdir shouldn't contain default ACL"
9729         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9730                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9731         true
9732 }
9733 run_test 103c "'cp -rp' won't set empty acl"
9734
9735 test_104a() {
9736         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9737
9738         touch $DIR/$tfile
9739         lfs df || error "lfs df failed"
9740         lfs df -ih || error "lfs df -ih failed"
9741         lfs df -h $DIR || error "lfs df -h $DIR failed"
9742         lfs df -i $DIR || error "lfs df -i $DIR failed"
9743         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9744         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9745
9746         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9747         lctl --device %$OSC deactivate
9748         lfs df || error "lfs df with deactivated OSC failed"
9749         lctl --device %$OSC activate
9750         # wait the osc back to normal
9751         wait_osc_import_ready client ost
9752
9753         lfs df || error "lfs df with reactivated OSC failed"
9754         rm -f $DIR/$tfile
9755 }
9756 run_test 104a "lfs df [-ih] [path] test ========================="
9757
9758 test_104b() {
9759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9760         [ $RUNAS_ID -eq $UID ] &&
9761                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9762
9763         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9764                         grep "Permission denied" | wc -l)))
9765         if [ $denied_cnt -ne 0 ]; then
9766                 error "lfs check servers test failed"
9767         fi
9768 }
9769 run_test 104b "$RUNAS lfs check servers test ===================="
9770
9771 test_105a() {
9772         # doesn't work on 2.4 kernels
9773         touch $DIR/$tfile
9774         if $(flock_is_enabled); then
9775                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9776         else
9777                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9778         fi
9779         rm -f $DIR/$tfile
9780 }
9781 run_test 105a "flock when mounted without -o flock test ========"
9782
9783 test_105b() {
9784         touch $DIR/$tfile
9785         if $(flock_is_enabled); then
9786                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9787         else
9788                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9789         fi
9790         rm -f $DIR/$tfile
9791 }
9792 run_test 105b "fcntl when mounted without -o flock test ========"
9793
9794 test_105c() {
9795         touch $DIR/$tfile
9796         if $(flock_is_enabled); then
9797                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9798         else
9799                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9800         fi
9801         rm -f $DIR/$tfile
9802 }
9803 run_test 105c "lockf when mounted without -o flock test"
9804
9805 test_105d() { # bug 15924
9806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9807
9808         test_mkdir $DIR/$tdir
9809         flock_is_enabled || skip_env "mount w/o flock enabled"
9810         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9811         $LCTL set_param fail_loc=0x80000315
9812         flocks_test 2 $DIR/$tdir
9813 }
9814 run_test 105d "flock race (should not freeze) ========"
9815
9816 test_105e() { # bug 22660 && 22040
9817         flock_is_enabled || skip_env "mount w/o flock enabled"
9818
9819         touch $DIR/$tfile
9820         flocks_test 3 $DIR/$tfile
9821 }
9822 run_test 105e "Two conflicting flocks from same process"
9823
9824 test_106() { #bug 10921
9825         test_mkdir $DIR/$tdir
9826         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9827         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9828 }
9829 run_test 106 "attempt exec of dir followed by chown of that dir"
9830
9831 test_107() {
9832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9833
9834         CDIR=`pwd`
9835         local file=core
9836
9837         cd $DIR
9838         rm -f $file
9839
9840         local save_pattern=$(sysctl -n kernel.core_pattern)
9841         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9842         sysctl -w kernel.core_pattern=$file
9843         sysctl -w kernel.core_uses_pid=0
9844
9845         ulimit -c unlimited
9846         sleep 60 &
9847         SLEEPPID=$!
9848
9849         sleep 1
9850
9851         kill -s 11 $SLEEPPID
9852         wait $SLEEPPID
9853         if [ -e $file ]; then
9854                 size=`stat -c%s $file`
9855                 [ $size -eq 0 ] && error "Fail to create core file $file"
9856         else
9857                 error "Fail to create core file $file"
9858         fi
9859         rm -f $file
9860         sysctl -w kernel.core_pattern=$save_pattern
9861         sysctl -w kernel.core_uses_pid=$save_uses_pid
9862         cd $CDIR
9863 }
9864 run_test 107 "Coredump on SIG"
9865
9866 test_110() {
9867         test_mkdir $DIR/$tdir
9868         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9869         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9870                 error "mkdir with 256 char should fail, but did not"
9871         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9872                 error "create with 255 char failed"
9873         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9874                 error "create with 256 char should fail, but did not"
9875
9876         ls -l $DIR/$tdir
9877         rm -rf $DIR/$tdir
9878 }
9879 run_test 110 "filename length checking"
9880
9881 #
9882 # Purpose: To verify dynamic thread (OSS) creation.
9883 #
9884 test_115() {
9885         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9886         remote_ost_nodsh && skip "remote OST with nodsh"
9887
9888         # Lustre does not stop service threads once they are started.
9889         # Reset number of running threads to default.
9890         stopall
9891         setupall
9892
9893         local OSTIO_pre
9894         local save_params="$TMP/sanity-$TESTNAME.parameters"
9895
9896         # Get ll_ost_io count before I/O
9897         OSTIO_pre=$(do_facet ost1 \
9898                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9899         # Exit if lustre is not running (ll_ost_io not running).
9900         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9901
9902         echo "Starting with $OSTIO_pre threads"
9903         local thread_max=$((OSTIO_pre * 2))
9904         local rpc_in_flight=$((thread_max * 2))
9905         # Number of I/O Process proposed to be started.
9906         local nfiles
9907         local facets=$(get_facets OST)
9908
9909         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9910         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9911
9912         # Set in_flight to $rpc_in_flight
9913         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9914                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9915         nfiles=${rpc_in_flight}
9916         # Set ost thread_max to $thread_max
9917         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9918
9919         # 5 Minutes should be sufficient for max number of OSS
9920         # threads(thread_max) to be created.
9921         local timeout=300
9922
9923         # Start I/O.
9924         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9925         test_mkdir $DIR/$tdir
9926         for i in $(seq $nfiles); do
9927                 local file=$DIR/$tdir/${tfile}-$i
9928                 $LFS setstripe -c -1 -i 0 $file
9929                 ($WTL $file $timeout)&
9930         done
9931
9932         # I/O Started - Wait for thread_started to reach thread_max or report
9933         # error if thread_started is more than thread_max.
9934         echo "Waiting for thread_started to reach thread_max"
9935         local thread_started=0
9936         local end_time=$((SECONDS + timeout))
9937
9938         while [ $SECONDS -le $end_time ] ; do
9939                 echo -n "."
9940                 # Get ost i/o thread_started count.
9941                 thread_started=$(do_facet ost1 \
9942                         "$LCTL get_param \
9943                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9944                 # Break out if thread_started is equal/greater than thread_max
9945                 if [[ $thread_started -ge $thread_max ]]; then
9946                         echo ll_ost_io thread_started $thread_started, \
9947                                 equal/greater than thread_max $thread_max
9948                         break
9949                 fi
9950                 sleep 1
9951         done
9952
9953         # Cleanup - We have the numbers, Kill i/o jobs if running.
9954         jobcount=($(jobs -p))
9955         for i in $(seq 0 $((${#jobcount[@]}-1)))
9956         do
9957                 kill -9 ${jobcount[$i]}
9958                 if [ $? -ne 0 ] ; then
9959                         echo Warning: \
9960                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9961                 fi
9962         done
9963
9964         # Cleanup files left by WTL binary.
9965         for i in $(seq $nfiles); do
9966                 local file=$DIR/$tdir/${tfile}-$i
9967                 rm -rf $file
9968                 if [ $? -ne 0 ] ; then
9969                         echo "Warning: Failed to delete file $file"
9970                 fi
9971         done
9972
9973         restore_lustre_params <$save_params
9974         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9975
9976         # Error out if no new thread has started or Thread started is greater
9977         # than thread max.
9978         if [[ $thread_started -le $OSTIO_pre ||
9979                         $thread_started -gt $thread_max ]]; then
9980                 error "ll_ost_io: thread_started $thread_started" \
9981                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9982                       "No new thread started or thread started greater " \
9983                       "than thread_max."
9984         fi
9985 }
9986 run_test 115 "verify dynamic thread creation===================="
9987
9988 free_min_max () {
9989         wait_delete_completed
9990         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9991         echo "OST kbytes available: ${AVAIL[@]}"
9992         MAXV=${AVAIL[0]}
9993         MAXI=0
9994         MINV=${AVAIL[0]}
9995         MINI=0
9996         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9997                 #echo OST $i: ${AVAIL[i]}kb
9998                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9999                         MAXV=${AVAIL[i]}
10000                         MAXI=$i
10001                 fi
10002                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
10003                         MINV=${AVAIL[i]}
10004                         MINI=$i
10005                 fi
10006         done
10007         echo "Min free space: OST $MINI: $MINV"
10008         echo "Max free space: OST $MAXI: $MAXV"
10009 }
10010
10011 test_116a() { # was previously test_116()
10012         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10013         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10014         remote_mds_nodsh && skip "remote MDS with nodsh"
10015
10016         echo -n "Free space priority "
10017         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
10018                 head -n1
10019         declare -a AVAIL
10020         free_min_max
10021
10022         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
10023         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
10024         trap simple_cleanup_common EXIT
10025
10026         # Check if we need to generate uneven OSTs
10027         test_mkdir -p $DIR/$tdir/OST${MINI}
10028         local FILL=$((MINV / 4))
10029         local DIFF=$((MAXV - MINV))
10030         local DIFF2=$((DIFF * 100 / MINV))
10031
10032         local threshold=$(do_facet $SINGLEMDS \
10033                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
10034         threshold=${threshold%%%}
10035         echo -n "Check for uneven OSTs: "
10036         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
10037
10038         if [[ $DIFF2 -gt $threshold ]]; then
10039                 echo "ok"
10040                 echo "Don't need to fill OST$MINI"
10041         else
10042                 # generate uneven OSTs. Write 2% over the QOS threshold value
10043                 echo "no"
10044                 DIFF=$((threshold - DIFF2 + 2))
10045                 DIFF2=$((MINV * DIFF / 100))
10046                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
10047                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
10048                         error "setstripe failed"
10049                 DIFF=$((DIFF2 / 2048))
10050                 i=0
10051                 while [ $i -lt $DIFF ]; do
10052                         i=$((i + 1))
10053                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
10054                                 bs=2M count=1 2>/dev/null
10055                         echo -n .
10056                 done
10057                 echo .
10058                 sync
10059                 sleep_maxage
10060                 free_min_max
10061         fi
10062
10063         DIFF=$((MAXV - MINV))
10064         DIFF2=$((DIFF * 100 / MINV))
10065         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
10066         if [ $DIFF2 -gt $threshold ]; then
10067                 echo "ok"
10068         else
10069                 echo "failed - QOS mode won't be used"
10070                 simple_cleanup_common
10071                 skip "QOS imbalance criteria not met"
10072         fi
10073
10074         MINI1=$MINI
10075         MINV1=$MINV
10076         MAXI1=$MAXI
10077         MAXV1=$MAXV
10078
10079         # now fill using QOS
10080         $LFS setstripe -c 1 $DIR/$tdir
10081         FILL=$((FILL / 200))
10082         if [ $FILL -gt 600 ]; then
10083                 FILL=600
10084         fi
10085         echo "writing $FILL files to QOS-assigned OSTs"
10086         i=0
10087         while [ $i -lt $FILL ]; do
10088                 i=$((i + 1))
10089                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
10090                         count=1 2>/dev/null
10091                 echo -n .
10092         done
10093         echo "wrote $i 200k files"
10094         sync
10095         sleep_maxage
10096
10097         echo "Note: free space may not be updated, so measurements might be off"
10098         free_min_max
10099         DIFF2=$((MAXV - MINV))
10100         echo "free space delta: orig $DIFF final $DIFF2"
10101         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
10102         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
10103         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
10104         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
10105         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
10106         if [[ $DIFF -gt 0 ]]; then
10107                 FILL=$((DIFF2 * 100 / DIFF - 100))
10108                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
10109         fi
10110
10111         # Figure out which files were written where
10112         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10113                awk '/'$MINI1': / {print $2; exit}')
10114         echo $UUID
10115         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10116         echo "$MINC files created on smaller OST $MINI1"
10117         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
10118                awk '/'$MAXI1': / {print $2; exit}')
10119         echo $UUID
10120         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
10121         echo "$MAXC files created on larger OST $MAXI1"
10122         if [[ $MINC -gt 0 ]]; then
10123                 FILL=$((MAXC * 100 / MINC - 100))
10124                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
10125         fi
10126         [[ $MAXC -gt $MINC ]] ||
10127                 error_ignore LU-9 "stripe QOS didn't balance free space"
10128         simple_cleanup_common
10129 }
10130 run_test 116a "stripe QOS: free space balance ==================="
10131
10132 test_116b() { # LU-2093
10133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10134         remote_mds_nodsh && skip "remote MDS with nodsh"
10135
10136 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
10137         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
10138                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
10139         [ -z "$old_rr" ] && skip "no QOS"
10140         do_facet $SINGLEMDS lctl set_param \
10141                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
10142         mkdir -p $DIR/$tdir
10143         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
10144         createmany -o $DIR/$tdir/f- 20 || error "can't create"
10145         do_facet $SINGLEMDS lctl set_param fail_loc=0
10146         rm -rf $DIR/$tdir
10147         do_facet $SINGLEMDS lctl set_param \
10148                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
10149 }
10150 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
10151
10152 test_117() # bug 10891
10153 {
10154         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10155
10156         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
10157         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
10158         lctl set_param fail_loc=0x21e
10159         > $DIR/$tfile || error "truncate failed"
10160         lctl set_param fail_loc=0
10161         echo "Truncate succeeded."
10162         rm -f $DIR/$tfile
10163 }
10164 run_test 117 "verify osd extend =========="
10165
10166 NO_SLOW_RESENDCOUNT=4
10167 export OLD_RESENDCOUNT=""
10168 set_resend_count () {
10169         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
10170         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
10171         lctl set_param -n $PROC_RESENDCOUNT $1
10172         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
10173 }
10174
10175 # for reduce test_118* time (b=14842)
10176 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10177
10178 # Reset async IO behavior after error case
10179 reset_async() {
10180         FILE=$DIR/reset_async
10181
10182         # Ensure all OSCs are cleared
10183         $LFS setstripe -c -1 $FILE
10184         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10185         sync
10186         rm $FILE
10187 }
10188
10189 test_118a() #bug 11710
10190 {
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192
10193         reset_async
10194
10195         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10196         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10197         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10198
10199         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10200                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10201                 return 1;
10202         fi
10203         rm -f $DIR/$tfile
10204 }
10205 run_test 118a "verify O_SYNC works =========="
10206
10207 test_118b()
10208 {
10209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10210         remote_ost_nodsh && skip "remote OST with nodsh"
10211
10212         reset_async
10213
10214         #define OBD_FAIL_SRV_ENOENT 0x217
10215         set_nodes_failloc "$(osts_nodes)" 0x217
10216         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10217         RC=$?
10218         set_nodes_failloc "$(osts_nodes)" 0
10219         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10220         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10221                     grep -c writeback)
10222
10223         if [[ $RC -eq 0 ]]; then
10224                 error "Must return error due to dropped pages, rc=$RC"
10225                 return 1;
10226         fi
10227
10228         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10229                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10230                 return 1;
10231         fi
10232
10233         echo "Dirty pages not leaked on ENOENT"
10234
10235         # Due to the above error the OSC will issue all RPCs syncronously
10236         # until a subsequent RPC completes successfully without error.
10237         $MULTIOP $DIR/$tfile Ow4096yc
10238         rm -f $DIR/$tfile
10239
10240         return 0
10241 }
10242 run_test 118b "Reclaim dirty pages on fatal error =========="
10243
10244 test_118c()
10245 {
10246         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10247
10248         # for 118c, restore the original resend count, LU-1940
10249         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10250                                 set_resend_count $OLD_RESENDCOUNT
10251         remote_ost_nodsh && skip "remote OST with nodsh"
10252
10253         reset_async
10254
10255         #define OBD_FAIL_OST_EROFS               0x216
10256         set_nodes_failloc "$(osts_nodes)" 0x216
10257
10258         # multiop should block due to fsync until pages are written
10259         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10260         MULTIPID=$!
10261         sleep 1
10262
10263         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10264                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10265         fi
10266
10267         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10268                     grep -c writeback)
10269         if [[ $WRITEBACK -eq 0 ]]; then
10270                 error "No page in writeback, writeback=$WRITEBACK"
10271         fi
10272
10273         set_nodes_failloc "$(osts_nodes)" 0
10274         wait $MULTIPID
10275         RC=$?
10276         if [[ $RC -ne 0 ]]; then
10277                 error "Multiop fsync failed, rc=$RC"
10278         fi
10279
10280         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10281         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10282                     grep -c writeback)
10283         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10284                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10285         fi
10286
10287         rm -f $DIR/$tfile
10288         echo "Dirty pages flushed via fsync on EROFS"
10289         return 0
10290 }
10291 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10292
10293 # continue to use small resend count to reduce test_118* time (b=14842)
10294 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10295
10296 test_118d()
10297 {
10298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10299         remote_ost_nodsh && skip "remote OST with nodsh"
10300
10301         reset_async
10302
10303         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10304         set_nodes_failloc "$(osts_nodes)" 0x214
10305         # multiop should block due to fsync until pages are written
10306         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10307         MULTIPID=$!
10308         sleep 1
10309
10310         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10311                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10312         fi
10313
10314         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10315                     grep -c writeback)
10316         if [[ $WRITEBACK -eq 0 ]]; then
10317                 error "No page in writeback, writeback=$WRITEBACK"
10318         fi
10319
10320         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10321         set_nodes_failloc "$(osts_nodes)" 0
10322
10323         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10324         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10325                     grep -c writeback)
10326         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10327                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10328         fi
10329
10330         rm -f $DIR/$tfile
10331         echo "Dirty pages gaurenteed flushed via fsync"
10332         return 0
10333 }
10334 run_test 118d "Fsync validation inject a delay of the bulk =========="
10335
10336 test_118f() {
10337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10338
10339         reset_async
10340
10341         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10342         lctl set_param fail_loc=0x8000040a
10343
10344         # Should simulate EINVAL error which is fatal
10345         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10346         RC=$?
10347         if [[ $RC -eq 0 ]]; then
10348                 error "Must return error due to dropped pages, rc=$RC"
10349         fi
10350
10351         lctl set_param fail_loc=0x0
10352
10353         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10354         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10355         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10356                     grep -c writeback)
10357         if [[ $LOCKED -ne 0 ]]; then
10358                 error "Locked pages remain in cache, locked=$LOCKED"
10359         fi
10360
10361         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10362                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10363         fi
10364
10365         rm -f $DIR/$tfile
10366         echo "No pages locked after fsync"
10367
10368         reset_async
10369         return 0
10370 }
10371 run_test 118f "Simulate unrecoverable OSC side error =========="
10372
10373 test_118g() {
10374         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10375
10376         reset_async
10377
10378         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10379         lctl set_param fail_loc=0x406
10380
10381         # simulate local -ENOMEM
10382         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10383         RC=$?
10384
10385         lctl set_param fail_loc=0
10386         if [[ $RC -eq 0 ]]; then
10387                 error "Must return error due to dropped pages, rc=$RC"
10388         fi
10389
10390         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10391         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10392         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10393                         grep -c writeback)
10394         if [[ $LOCKED -ne 0 ]]; then
10395                 error "Locked pages remain in cache, locked=$LOCKED"
10396         fi
10397
10398         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10399                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10400         fi
10401
10402         rm -f $DIR/$tfile
10403         echo "No pages locked after fsync"
10404
10405         reset_async
10406         return 0
10407 }
10408 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10409
10410 test_118h() {
10411         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10412         remote_ost_nodsh && skip "remote OST with nodsh"
10413
10414         reset_async
10415
10416         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10417         set_nodes_failloc "$(osts_nodes)" 0x20e
10418         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10419         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10420         RC=$?
10421
10422         set_nodes_failloc "$(osts_nodes)" 0
10423         if [[ $RC -eq 0 ]]; then
10424                 error "Must return error due to dropped pages, rc=$RC"
10425         fi
10426
10427         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10428         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10429         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10430                     grep -c writeback)
10431         if [[ $LOCKED -ne 0 ]]; then
10432                 error "Locked pages remain in cache, locked=$LOCKED"
10433         fi
10434
10435         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10436                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10437         fi
10438
10439         rm -f $DIR/$tfile
10440         echo "No pages locked after fsync"
10441
10442         return 0
10443 }
10444 run_test 118h "Verify timeout in handling recoverables errors  =========="
10445
10446 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10447
10448 test_118i() {
10449         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10450         remote_ost_nodsh && skip "remote OST with nodsh"
10451
10452         reset_async
10453
10454         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10455         set_nodes_failloc "$(osts_nodes)" 0x20e
10456
10457         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10458         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10459         PID=$!
10460         sleep 5
10461         set_nodes_failloc "$(osts_nodes)" 0
10462
10463         wait $PID
10464         RC=$?
10465         if [[ $RC -ne 0 ]]; then
10466                 error "got error, but should be not, rc=$RC"
10467         fi
10468
10469         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10470         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10471         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10472         if [[ $LOCKED -ne 0 ]]; then
10473                 error "Locked pages remain in cache, locked=$LOCKED"
10474         fi
10475
10476         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10477                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10478         fi
10479
10480         rm -f $DIR/$tfile
10481         echo "No pages locked after fsync"
10482
10483         return 0
10484 }
10485 run_test 118i "Fix error before timeout in recoverable error  =========="
10486
10487 [ "$SLOW" = "no" ] && set_resend_count 4
10488
10489 test_118j() {
10490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10491         remote_ost_nodsh && skip "remote OST with nodsh"
10492
10493         reset_async
10494
10495         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10496         set_nodes_failloc "$(osts_nodes)" 0x220
10497
10498         # return -EIO from OST
10499         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10500         RC=$?
10501         set_nodes_failloc "$(osts_nodes)" 0x0
10502         if [[ $RC -eq 0 ]]; then
10503                 error "Must return error due to dropped pages, rc=$RC"
10504         fi
10505
10506         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10507         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10508         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10509         if [[ $LOCKED -ne 0 ]]; then
10510                 error "Locked pages remain in cache, locked=$LOCKED"
10511         fi
10512
10513         # in recoverable error on OST we want resend and stay until it finished
10514         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10515                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10516         fi
10517
10518         rm -f $DIR/$tfile
10519         echo "No pages locked after fsync"
10520
10521         return 0
10522 }
10523 run_test 118j "Simulate unrecoverable OST side error =========="
10524
10525 test_118k()
10526 {
10527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10528         remote_ost_nodsh && skip "remote OSTs with nodsh"
10529
10530         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10531         set_nodes_failloc "$(osts_nodes)" 0x20e
10532         test_mkdir $DIR/$tdir
10533
10534         for ((i=0;i<10;i++)); do
10535                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10536                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10537                 SLEEPPID=$!
10538                 sleep 0.500s
10539                 kill $SLEEPPID
10540                 wait $SLEEPPID
10541         done
10542
10543         set_nodes_failloc "$(osts_nodes)" 0
10544         rm -rf $DIR/$tdir
10545 }
10546 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10547
10548 test_118l() # LU-646
10549 {
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551
10552         test_mkdir $DIR/$tdir
10553         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10554         rm -rf $DIR/$tdir
10555 }
10556 run_test 118l "fsync dir"
10557
10558 test_118m() # LU-3066
10559 {
10560         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10561
10562         test_mkdir $DIR/$tdir
10563         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10564         rm -rf $DIR/$tdir
10565 }
10566 run_test 118m "fdatasync dir ========="
10567
10568 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10569
10570 test_118n()
10571 {
10572         local begin
10573         local end
10574
10575         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10576         remote_ost_nodsh && skip "remote OSTs with nodsh"
10577
10578         # Sleep to avoid a cached response.
10579         #define OBD_STATFS_CACHE_SECONDS 1
10580         sleep 2
10581
10582         # Inject a 10 second delay in the OST_STATFS handler.
10583         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10584         set_nodes_failloc "$(osts_nodes)" 0x242
10585
10586         begin=$SECONDS
10587         stat --file-system $MOUNT > /dev/null
10588         end=$SECONDS
10589
10590         set_nodes_failloc "$(osts_nodes)" 0
10591
10592         if ((end - begin > 20)); then
10593             error "statfs took $((end - begin)) seconds, expected 10"
10594         fi
10595 }
10596 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10597
10598 test_119a() # bug 11737
10599 {
10600         BSIZE=$((512 * 1024))
10601         directio write $DIR/$tfile 0 1 $BSIZE
10602         # We ask to read two blocks, which is more than a file size.
10603         # directio will indicate an error when requested and actual
10604         # sizes aren't equeal (a normal situation in this case) and
10605         # print actual read amount.
10606         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10607         if [ "$NOB" != "$BSIZE" ]; then
10608                 error "read $NOB bytes instead of $BSIZE"
10609         fi
10610         rm -f $DIR/$tfile
10611 }
10612 run_test 119a "Short directIO read must return actual read amount"
10613
10614 test_119b() # bug 11737
10615 {
10616         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10617
10618         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10619         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10620         sync
10621         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10622                 error "direct read failed"
10623         rm -f $DIR/$tfile
10624 }
10625 run_test 119b "Sparse directIO read must return actual read amount"
10626
10627 test_119c() # bug 13099
10628 {
10629         BSIZE=1048576
10630         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10631         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10632         rm -f $DIR/$tfile
10633 }
10634 run_test 119c "Testing for direct read hitting hole"
10635
10636 test_119d() # bug 15950
10637 {
10638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10639
10640         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10641         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10642         BSIZE=1048576
10643         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10644         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10645         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10646         lctl set_param fail_loc=0x40d
10647         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10648         pid_dio=$!
10649         sleep 1
10650         cat $DIR/$tfile > /dev/null &
10651         lctl set_param fail_loc=0
10652         pid_reads=$!
10653         wait $pid_dio
10654         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10655         sleep 2
10656         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10657         error "the read rpcs have not completed in 2s"
10658         rm -f $DIR/$tfile
10659         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10660 }
10661 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10662
10663 test_120a() {
10664         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10665         remote_mds_nodsh && skip "remote MDS with nodsh"
10666         test_mkdir -i0 -c1 $DIR/$tdir
10667         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10668                 skip_env "no early lock cancel on server"
10669
10670         lru_resize_disable mdc
10671         lru_resize_disable osc
10672         cancel_lru_locks mdc
10673         # asynchronous object destroy at MDT could cause bl ast to client
10674         cancel_lru_locks osc
10675
10676         stat $DIR/$tdir > /dev/null
10677         can1=$(do_facet mds1 \
10678                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10679                awk '/ldlm_cancel/ {print $2}')
10680         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10681                awk '/ldlm_bl_callback/ {print $2}')
10682         test_mkdir -i0 -c1 $DIR/$tdir/d1
10683         can2=$(do_facet mds1 \
10684                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10685                awk '/ldlm_cancel/ {print $2}')
10686         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10687                awk '/ldlm_bl_callback/ {print $2}')
10688         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10689         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10690         lru_resize_enable mdc
10691         lru_resize_enable osc
10692 }
10693 run_test 120a "Early Lock Cancel: mkdir test"
10694
10695 test_120b() {
10696         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10697         remote_mds_nodsh && skip "remote MDS with nodsh"
10698         test_mkdir $DIR/$tdir
10699         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10700                 skip_env "no early lock cancel on server"
10701
10702         lru_resize_disable mdc
10703         lru_resize_disable osc
10704         cancel_lru_locks mdc
10705         stat $DIR/$tdir > /dev/null
10706         can1=$(do_facet $SINGLEMDS \
10707                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10708                awk '/ldlm_cancel/ {print $2}')
10709         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10710                awk '/ldlm_bl_callback/ {print $2}')
10711         touch $DIR/$tdir/f1
10712         can2=$(do_facet $SINGLEMDS \
10713                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10714                awk '/ldlm_cancel/ {print $2}')
10715         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10716                awk '/ldlm_bl_callback/ {print $2}')
10717         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10718         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10719         lru_resize_enable mdc
10720         lru_resize_enable osc
10721 }
10722 run_test 120b "Early Lock Cancel: create test"
10723
10724 test_120c() {
10725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10726         remote_mds_nodsh && skip "remote MDS with nodsh"
10727         test_mkdir -i0 -c1 $DIR/$tdir
10728         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10729                 skip "no early lock cancel on server"
10730
10731         lru_resize_disable mdc
10732         lru_resize_disable osc
10733         test_mkdir -i0 -c1 $DIR/$tdir/d1
10734         test_mkdir -i0 -c1 $DIR/$tdir/d2
10735         touch $DIR/$tdir/d1/f1
10736         cancel_lru_locks mdc
10737         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10738         can1=$(do_facet mds1 \
10739                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10740                awk '/ldlm_cancel/ {print $2}')
10741         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10742                awk '/ldlm_bl_callback/ {print $2}')
10743         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10744         can2=$(do_facet mds1 \
10745                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10746                awk '/ldlm_cancel/ {print $2}')
10747         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10748                awk '/ldlm_bl_callback/ {print $2}')
10749         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10750         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10751         lru_resize_enable mdc
10752         lru_resize_enable osc
10753 }
10754 run_test 120c "Early Lock Cancel: link test"
10755
10756 test_120d() {
10757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10758         remote_mds_nodsh && skip "remote MDS with nodsh"
10759         test_mkdir -i0 -c1 $DIR/$tdir
10760         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10761                 skip_env "no early lock cancel on server"
10762
10763         lru_resize_disable mdc
10764         lru_resize_disable osc
10765         touch $DIR/$tdir
10766         cancel_lru_locks mdc
10767         stat $DIR/$tdir > /dev/null
10768         can1=$(do_facet mds1 \
10769                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10770                awk '/ldlm_cancel/ {print $2}')
10771         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10772                awk '/ldlm_bl_callback/ {print $2}')
10773         chmod a+x $DIR/$tdir
10774         can2=$(do_facet mds1 \
10775                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10776                awk '/ldlm_cancel/ {print $2}')
10777         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10778                awk '/ldlm_bl_callback/ {print $2}')
10779         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10780         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10781         lru_resize_enable mdc
10782         lru_resize_enable osc
10783 }
10784 run_test 120d "Early Lock Cancel: setattr test"
10785
10786 test_120e() {
10787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10788         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10789                 skip_env "no early lock cancel on server"
10790         remote_mds_nodsh && skip "remote MDS with nodsh"
10791
10792         local dlmtrace_set=false
10793
10794         test_mkdir -i0 -c1 $DIR/$tdir
10795         lru_resize_disable mdc
10796         lru_resize_disable osc
10797         ! $LCTL get_param debug | grep -q dlmtrace &&
10798                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10799         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10800         cancel_lru_locks mdc
10801         cancel_lru_locks osc
10802         dd if=$DIR/$tdir/f1 of=/dev/null
10803         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10804         # XXX client can not do early lock cancel of OST lock
10805         # during unlink (LU-4206), so cancel osc lock now.
10806         sleep 2
10807         cancel_lru_locks osc
10808         can1=$(do_facet mds1 \
10809                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10810                awk '/ldlm_cancel/ {print $2}')
10811         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10812                awk '/ldlm_bl_callback/ {print $2}')
10813         unlink $DIR/$tdir/f1
10814         sleep 5
10815         can2=$(do_facet mds1 \
10816                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10817                awk '/ldlm_cancel/ {print $2}')
10818         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10819                awk '/ldlm_bl_callback/ {print $2}')
10820         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10821                 $LCTL dk $TMP/cancel.debug.txt
10822         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10823                 $LCTL dk $TMP/blocking.debug.txt
10824         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10825         lru_resize_enable mdc
10826         lru_resize_enable osc
10827 }
10828 run_test 120e "Early Lock Cancel: unlink test"
10829
10830 test_120f() {
10831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10832         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10833                 skip_env "no early lock cancel on server"
10834         remote_mds_nodsh && skip "remote MDS with nodsh"
10835
10836         test_mkdir -i0 -c1 $DIR/$tdir
10837         lru_resize_disable mdc
10838         lru_resize_disable osc
10839         test_mkdir -i0 -c1 $DIR/$tdir/d1
10840         test_mkdir -i0 -c1 $DIR/$tdir/d2
10841         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10842         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10843         cancel_lru_locks mdc
10844         cancel_lru_locks osc
10845         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10846         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10847         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10848         # XXX client can not do early lock cancel of OST lock
10849         # during rename (LU-4206), so cancel osc lock now.
10850         sleep 2
10851         cancel_lru_locks osc
10852         can1=$(do_facet mds1 \
10853                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10854                awk '/ldlm_cancel/ {print $2}')
10855         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10856                awk '/ldlm_bl_callback/ {print $2}')
10857         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10858         sleep 5
10859         can2=$(do_facet mds1 \
10860                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10861                awk '/ldlm_cancel/ {print $2}')
10862         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10863                awk '/ldlm_bl_callback/ {print $2}')
10864         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10865         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10866         lru_resize_enable mdc
10867         lru_resize_enable osc
10868 }
10869 run_test 120f "Early Lock Cancel: rename test"
10870
10871 test_120g() {
10872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10873         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10874                 skip_env "no early lock cancel on server"
10875         remote_mds_nodsh && skip "remote MDS with nodsh"
10876
10877         lru_resize_disable mdc
10878         lru_resize_disable osc
10879         count=10000
10880         echo create $count files
10881         test_mkdir $DIR/$tdir
10882         cancel_lru_locks mdc
10883         cancel_lru_locks osc
10884         t0=$(date +%s)
10885
10886         can0=$(do_facet $SINGLEMDS \
10887                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10888                awk '/ldlm_cancel/ {print $2}')
10889         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10890                awk '/ldlm_bl_callback/ {print $2}')
10891         createmany -o $DIR/$tdir/f $count
10892         sync
10893         can1=$(do_facet $SINGLEMDS \
10894                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10895                awk '/ldlm_cancel/ {print $2}')
10896         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10897                awk '/ldlm_bl_callback/ {print $2}')
10898         t1=$(date +%s)
10899         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10900         echo rm $count files
10901         rm -r $DIR/$tdir
10902         sync
10903         can2=$(do_facet $SINGLEMDS \
10904                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10905                awk '/ldlm_cancel/ {print $2}')
10906         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10907                awk '/ldlm_bl_callback/ {print $2}')
10908         t2=$(date +%s)
10909         echo total: $count removes in $((t2-t1))
10910         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10911         sleep 2
10912         # wait for commitment of removal
10913         lru_resize_enable mdc
10914         lru_resize_enable osc
10915 }
10916 run_test 120g "Early Lock Cancel: performance test"
10917
10918 test_121() { #bug #10589
10919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10920
10921         rm -rf $DIR/$tfile
10922         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10923 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10924         lctl set_param fail_loc=0x310
10925         cancel_lru_locks osc > /dev/null
10926         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10927         lctl set_param fail_loc=0
10928         [[ $reads -eq $writes ]] ||
10929                 error "read $reads blocks, must be $writes blocks"
10930 }
10931 run_test 121 "read cancel race ========="
10932
10933 test_123a() { # was test 123, statahead(bug 11401)
10934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10935
10936         SLOWOK=0
10937         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10938                 log "testing UP system. Performance may be lower than expected."
10939                 SLOWOK=1
10940         fi
10941
10942         rm -rf $DIR/$tdir
10943         test_mkdir $DIR/$tdir
10944         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10945         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10946         MULT=10
10947         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10948                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10949
10950                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10951                 lctl set_param -n llite.*.statahead_max 0
10952                 lctl get_param llite.*.statahead_max
10953                 cancel_lru_locks mdc
10954                 cancel_lru_locks osc
10955                 stime=`date +%s`
10956                 time ls -l $DIR/$tdir | wc -l
10957                 etime=`date +%s`
10958                 delta=$((etime - stime))
10959                 log "ls $i files without statahead: $delta sec"
10960                 lctl set_param llite.*.statahead_max=$max
10961
10962                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10963                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10964                 cancel_lru_locks mdc
10965                 cancel_lru_locks osc
10966                 stime=`date +%s`
10967                 time ls -l $DIR/$tdir | wc -l
10968                 etime=`date +%s`
10969                 delta_sa=$((etime - stime))
10970                 log "ls $i files with statahead: $delta_sa sec"
10971                 lctl get_param -n llite.*.statahead_stats
10972                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10973
10974                 [[ $swrong -lt $ewrong ]] &&
10975                         log "statahead was stopped, maybe too many locks held!"
10976                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10977
10978                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10979                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10980                     lctl set_param -n llite.*.statahead_max 0
10981                     lctl get_param llite.*.statahead_max
10982                     cancel_lru_locks mdc
10983                     cancel_lru_locks osc
10984                     stime=`date +%s`
10985                     time ls -l $DIR/$tdir | wc -l
10986                     etime=`date +%s`
10987                     delta=$((etime - stime))
10988                     log "ls $i files again without statahead: $delta sec"
10989                     lctl set_param llite.*.statahead_max=$max
10990                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10991                         if [  $SLOWOK -eq 0 ]; then
10992                                 error "ls $i files is slower with statahead!"
10993                         else
10994                                 log "ls $i files is slower with statahead!"
10995                         fi
10996                         break
10997                     fi
10998                 fi
10999
11000                 [ $delta -gt 20 ] && break
11001                 [ $delta -gt 8 ] && MULT=$((50 / delta))
11002                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
11003         done
11004         log "ls done"
11005
11006         stime=`date +%s`
11007         rm -r $DIR/$tdir
11008         sync
11009         etime=`date +%s`
11010         delta=$((etime - stime))
11011         log "rm -r $DIR/$tdir/: $delta seconds"
11012         log "rm done"
11013         lctl get_param -n llite.*.statahead_stats
11014 }
11015 run_test 123a "verify statahead work"
11016
11017 test_123b () { # statahead(bug 15027)
11018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11019
11020         test_mkdir $DIR/$tdir
11021         createmany -o $DIR/$tdir/$tfile-%d 1000
11022
11023         cancel_lru_locks mdc
11024         cancel_lru_locks osc
11025
11026 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
11027         lctl set_param fail_loc=0x80000803
11028         ls -lR $DIR/$tdir > /dev/null
11029         log "ls done"
11030         lctl set_param fail_loc=0x0
11031         lctl get_param -n llite.*.statahead_stats
11032         rm -r $DIR/$tdir
11033         sync
11034
11035 }
11036 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
11037
11038 test_124a() {
11039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11040         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11041                 skip_env "no lru resize on server"
11042
11043         local NR=2000
11044
11045         test_mkdir $DIR/$tdir
11046
11047         log "create $NR files at $DIR/$tdir"
11048         createmany -o $DIR/$tdir/f $NR ||
11049                 error "failed to create $NR files in $DIR/$tdir"
11050
11051         cancel_lru_locks mdc
11052         ls -l $DIR/$tdir > /dev/null
11053
11054         local NSDIR=""
11055         local LRU_SIZE=0
11056         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
11057                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
11058                 LRU_SIZE=$($LCTL get_param -n $PARAM)
11059                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
11060                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
11061                         log "NSDIR=$NSDIR"
11062                         log "NS=$(basename $NSDIR)"
11063                         break
11064                 fi
11065         done
11066
11067         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
11068                 skip "Not enough cached locks created!"
11069         fi
11070         log "LRU=$LRU_SIZE"
11071
11072         local SLEEP=30
11073
11074         # We know that lru resize allows one client to hold $LIMIT locks
11075         # for 10h. After that locks begin to be killed by client.
11076         local MAX_HRS=10
11077         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
11078         log "LIMIT=$LIMIT"
11079         if [ $LIMIT -lt $LRU_SIZE ]; then
11080                 skip "Limit is too small $LIMIT"
11081         fi
11082
11083         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
11084         # killing locks. Some time was spent for creating locks. This means
11085         # that up to the moment of sleep finish we must have killed some of
11086         # them (10-100 locks). This depends on how fast ther were created.
11087         # Many of them were touched in almost the same moment and thus will
11088         # be killed in groups.
11089         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
11090
11091         # Use $LRU_SIZE_B here to take into account real number of locks
11092         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
11093         local LRU_SIZE_B=$LRU_SIZE
11094         log "LVF=$LVF"
11095         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
11096         log "OLD_LVF=$OLD_LVF"
11097         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
11098
11099         # Let's make sure that we really have some margin. Client checks
11100         # cached locks every 10 sec.
11101         SLEEP=$((SLEEP+20))
11102         log "Sleep ${SLEEP} sec"
11103         local SEC=0
11104         while ((SEC<$SLEEP)); do
11105                 echo -n "..."
11106                 sleep 5
11107                 SEC=$((SEC+5))
11108                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
11109                 echo -n "$LRU_SIZE"
11110         done
11111         echo ""
11112         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
11113         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
11114
11115         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
11116                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
11117                 unlinkmany $DIR/$tdir/f $NR
11118                 return
11119         }
11120
11121         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
11122         log "unlink $NR files at $DIR/$tdir"
11123         unlinkmany $DIR/$tdir/f $NR
11124 }
11125 run_test 124a "lru resize ======================================="
11126
11127 get_max_pool_limit()
11128 {
11129         local limit=$($LCTL get_param \
11130                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
11131         local max=0
11132         for l in $limit; do
11133                 if [[ $l -gt $max ]]; then
11134                         max=$l
11135                 fi
11136         done
11137         echo $max
11138 }
11139
11140 test_124b() {
11141         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11142         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11143                 skip_env "no lru resize on server"
11144
11145         LIMIT=$(get_max_pool_limit)
11146
11147         NR=$(($(default_lru_size)*20))
11148         if [[ $NR -gt $LIMIT ]]; then
11149                 log "Limit lock number by $LIMIT locks"
11150                 NR=$LIMIT
11151         fi
11152
11153         IFree=$(mdsrate_inodes_available)
11154         if [ $IFree -lt $NR ]; then
11155                 log "Limit lock number by $IFree inodes"
11156                 NR=$IFree
11157         fi
11158
11159         lru_resize_disable mdc
11160         test_mkdir -p $DIR/$tdir/disable_lru_resize
11161
11162         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
11163         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
11164         cancel_lru_locks mdc
11165         stime=`date +%s`
11166         PID=""
11167         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11168         PID="$PID $!"
11169         sleep 2
11170         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11171         PID="$PID $!"
11172         sleep 2
11173         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
11174         PID="$PID $!"
11175         wait $PID
11176         etime=`date +%s`
11177         nolruresize_delta=$((etime-stime))
11178         log "ls -la time: $nolruresize_delta seconds"
11179         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11180         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11181
11182         lru_resize_enable mdc
11183         test_mkdir -p $DIR/$tdir/enable_lru_resize
11184
11185         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11186         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11187         cancel_lru_locks mdc
11188         stime=`date +%s`
11189         PID=""
11190         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11191         PID="$PID $!"
11192         sleep 2
11193         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11194         PID="$PID $!"
11195         sleep 2
11196         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11197         PID="$PID $!"
11198         wait $PID
11199         etime=`date +%s`
11200         lruresize_delta=$((etime-stime))
11201         log "ls -la time: $lruresize_delta seconds"
11202         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11203
11204         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11205                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11206         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11207                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11208         else
11209                 log "lru resize performs the same with no lru resize"
11210         fi
11211         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11212 }
11213 run_test 124b "lru resize (performance test) ======================="
11214
11215 test_124c() {
11216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11217         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11218                 skip_env "no lru resize on server"
11219
11220         # cache ununsed locks on client
11221         local nr=100
11222         cancel_lru_locks mdc
11223         test_mkdir $DIR/$tdir
11224         createmany -o $DIR/$tdir/f $nr ||
11225                 error "failed to create $nr files in $DIR/$tdir"
11226         ls -l $DIR/$tdir > /dev/null
11227
11228         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11229         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11230         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11231         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11232         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11233
11234         # set lru_max_age to 1 sec
11235         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11236         echo "sleep $((recalc_p * 2)) seconds..."
11237         sleep $((recalc_p * 2))
11238
11239         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11240         # restore lru_max_age
11241         $LCTL set_param -n $nsdir.lru_max_age $max_age
11242         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11243         unlinkmany $DIR/$tdir/f $nr
11244 }
11245 run_test 124c "LRUR cancel very aged locks"
11246
11247 test_124d() {
11248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11249         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11250                 skip_env "no lru resize on server"
11251
11252         # cache ununsed locks on client
11253         local nr=100
11254
11255         lru_resize_disable mdc
11256         stack_trap "lru_resize_enable mdc" EXIT
11257
11258         cancel_lru_locks mdc
11259
11260         # asynchronous object destroy at MDT could cause bl ast to client
11261         test_mkdir $DIR/$tdir
11262         createmany -o $DIR/$tdir/f $nr ||
11263                 error "failed to create $nr files in $DIR/$tdir"
11264         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11265
11266         ls -l $DIR/$tdir > /dev/null
11267
11268         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11269         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11270         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11271         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11272
11273         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11274
11275         # set lru_max_age to 1 sec
11276         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11277         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11278
11279         echo "sleep $((recalc_p * 2)) seconds..."
11280         sleep $((recalc_p * 2))
11281
11282         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11283
11284         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11285 }
11286 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11287
11288 test_125() { # 13358
11289         $LCTL get_param -n llite.*.client_type | grep -q local ||
11290                 skip "must run as local client"
11291         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11292                 skip_env "must have acl enabled"
11293         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11294
11295         test_mkdir $DIR/$tdir
11296         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11297         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11298         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11299 }
11300 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11301
11302 test_126() { # bug 12829/13455
11303         $GSS && skip_env "must run as gss disabled"
11304         $LCTL get_param -n llite.*.client_type | grep -q local ||
11305                 skip "must run as local client"
11306         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11307
11308         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11309         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11310         rm -f $DIR/$tfile
11311         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11312 }
11313 run_test 126 "check that the fsgid provided by the client is taken into account"
11314
11315 test_127a() { # bug 15521
11316         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11317
11318         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11319         $LCTL set_param osc.*.stats=0
11320         FSIZE=$((2048 * 1024))
11321         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
11322         cancel_lru_locks osc
11323         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
11324
11325         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
11326         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
11327                 echo "got $COUNT $NAME"
11328                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
11329                 eval $NAME=$COUNT || error "Wrong proc format"
11330
11331                 case $NAME in
11332                         read_bytes|write_bytes)
11333                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
11334                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
11335                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
11336                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
11337                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
11338                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
11339                                 error "sumsquare is too small: $SUMSQ"
11340                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
11341                                 error "sumsquare is too big: $SUMSQ"
11342                         ;;
11343                         *) ;;
11344                 esac
11345         done < $DIR/${tfile}.tmp
11346
11347         #check that we actually got some stats
11348         [ "$read_bytes" ] || error "Missing read_bytes stats"
11349         [ "$write_bytes" ] || error "Missing write_bytes stats"
11350         [ "$read_bytes" != 0 ] || error "no read done"
11351         [ "$write_bytes" != 0 ] || error "no write done"
11352 }
11353 run_test 127a "verify the client stats are sane"
11354
11355 test_127b() { # bug LU-333
11356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11357         local name count samp unit min max sum sumsq
11358
11359         $LCTL set_param llite.*.stats=0
11360
11361         # perform 2 reads and writes so MAX is different from SUM.
11362         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11363         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11364         cancel_lru_locks osc
11365         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11366         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11367
11368         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11369         while read name count samp unit min max sum sumsq; do
11370                 echo "got $count $name"
11371                 eval $name=$count || error "Wrong proc format"
11372
11373                 case $name in
11374                 read_bytes)
11375                         [ $count -ne 2 ] && error "count is not 2: $count"
11376                         [ $min -ne $PAGE_SIZE ] &&
11377                                 error "min is not $PAGE_SIZE: $min"
11378                         [ $max -ne $PAGE_SIZE ] &&
11379                                 error "max is incorrect: $max"
11380                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11381                                 error "sum is wrong: $sum"
11382                         ;;
11383                 write_bytes)
11384                         [ $count -ne 2 ] && error "count is not 2: $count"
11385                         [ $min -ne $PAGE_SIZE ] &&
11386                                 error "min is not $PAGE_SIZE: $min"
11387                         [ $max -ne $PAGE_SIZE ] &&
11388                                 error "max is incorrect: $max"
11389                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11390                                 error "sum is wrong: $sum"
11391                         ;;
11392                 *) ;;
11393                 esac
11394         done < $TMP/$tfile.tmp
11395
11396         #check that we actually got some stats
11397         [ "$read_bytes" ] || error "Missing read_bytes stats"
11398         [ "$write_bytes" ] || error "Missing write_bytes stats"
11399         [ "$read_bytes" != 0 ] || error "no read done"
11400         [ "$write_bytes" != 0 ] || error "no write done"
11401
11402         rm -f $TMP/${tfile}.tmp
11403 }
11404 run_test 127b "verify the llite client stats are sane"
11405
11406 test_127c() { # LU-12394
11407         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11408         local size
11409         local bsize
11410         local reads
11411         local writes
11412         local count
11413
11414         $LCTL set_param llite.*.extents_stats=1
11415         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11416
11417         # Use two stripes so there is enough space in default config
11418         $LFS setstripe -c 2 $DIR/$tfile
11419
11420         # Extent stats start at 0-4K and go in power of two buckets
11421         # LL_HIST_START = 12 --> 2^12 = 4K
11422         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11423         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11424         # small configs
11425         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11426                 do
11427                 # Write and read, 2x each, second time at a non-zero offset
11428                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11429                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11430                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11431                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11432                 rm -f $DIR/$tfile
11433         done
11434
11435         $LCTL get_param llite.*.extents_stats
11436
11437         count=2
11438         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11439                 do
11440                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11441                                 grep -m 1 $bsize)
11442                 reads=$(echo $bucket | awk '{print $5}')
11443                 writes=$(echo $bucket | awk '{print $9}')
11444                 [ "$reads" -eq $count ] ||
11445                         error "$reads reads in < $bsize bucket, expect $count"
11446                 [ "$writes" -eq $count ] ||
11447                         error "$writes writes in < $bsize bucket, expect $count"
11448         done
11449
11450         # Test mmap write and read
11451         $LCTL set_param llite.*.extents_stats=c
11452         size=512
11453         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11454         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11455         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11456
11457         $LCTL get_param llite.*.extents_stats
11458
11459         count=$(((size*1024) / PAGE_SIZE))
11460
11461         bsize=$((2 * PAGE_SIZE / 1024))K
11462
11463         bucket=$($LCTL get_param -n llite.*.extents_stats |
11464                         grep -m 1 $bsize)
11465         reads=$(echo $bucket | awk '{print $5}')
11466         writes=$(echo $bucket | awk '{print $9}')
11467         # mmap writes fault in the page first, creating an additonal read
11468         [ "$reads" -eq $((2 * count)) ] ||
11469                 error "$reads reads in < $bsize bucket, expect $count"
11470         [ "$writes" -eq $count ] ||
11471                 error "$writes writes in < $bsize bucket, expect $count"
11472 }
11473 run_test 127c "test llite extent stats with regular & mmap i/o"
11474
11475 test_128() { # bug 15212
11476         touch $DIR/$tfile
11477         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11478                 find $DIR/$tfile
11479                 find $DIR/$tfile
11480         EOF
11481
11482         result=$(grep error $TMP/$tfile.log)
11483         rm -f $DIR/$tfile $TMP/$tfile.log
11484         [ -z "$result" ] ||
11485                 error "consecutive find's under interactive lfs failed"
11486 }
11487 run_test 128 "interactive lfs for 2 consecutive find's"
11488
11489 set_dir_limits () {
11490         local mntdev
11491         local canondev
11492         local node
11493
11494         local ldproc=/proc/fs/ldiskfs
11495         local facets=$(get_facets MDS)
11496
11497         for facet in ${facets//,/ }; do
11498                 canondev=$(ldiskfs_canon \
11499                            *.$(convert_facet2label $facet).mntdev $facet)
11500                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11501                         ldproc=/sys/fs/ldiskfs
11502                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11503                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11504         done
11505 }
11506
11507 check_mds_dmesg() {
11508         local facets=$(get_facets MDS)
11509         for facet in ${facets//,/ }; do
11510                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11511         done
11512         return 1
11513 }
11514
11515 test_129() {
11516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11517         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11518                 skip "Need MDS version with at least 2.5.56"
11519         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11520                 skip_env "ldiskfs only test"
11521         fi
11522         remote_mds_nodsh && skip "remote MDS with nodsh"
11523
11524         local ENOSPC=28
11525         local EFBIG=27
11526         local has_warning=false
11527
11528         rm -rf $DIR/$tdir
11529         mkdir -p $DIR/$tdir
11530
11531         # block size of mds1
11532         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11533         set_dir_limits $maxsize $maxsize
11534         local dirsize=$(stat -c%s "$DIR/$tdir")
11535         local nfiles=0
11536         while [[ $dirsize -le $maxsize ]]; do
11537                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11538                 rc=$?
11539                 if ! $has_warning; then
11540                         check_mds_dmesg '"is approaching"' && has_warning=true
11541                 fi
11542                 # check two errors:
11543                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11544                 # EFBIG for previous versions included in ldiskfs series
11545                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11546                         set_dir_limits 0 0
11547                         echo "return code $rc received as expected"
11548
11549                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11550                                 error_exit "create failed w/o dir size limit"
11551
11552                         check_mds_dmesg '"has reached"' ||
11553                                 error_exit "reached message should be output"
11554
11555                         [ $has_warning = "false" ] &&
11556                                 error_exit "warning message should be output"
11557
11558                         dirsize=$(stat -c%s "$DIR/$tdir")
11559
11560                         [[ $dirsize -ge $maxsize ]] && return 0
11561                         error_exit "current dir size $dirsize, " \
11562                                    "previous limit $maxsize"
11563                 elif [ $rc -ne 0 ]; then
11564                         set_dir_limits 0 0
11565                         error_exit "return $rc received instead of expected " \
11566                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11567                 fi
11568                 nfiles=$((nfiles + 1))
11569                 dirsize=$(stat -c%s "$DIR/$tdir")
11570         done
11571
11572         set_dir_limits 0 0
11573         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11574 }
11575 run_test 129 "test directory size limit ========================"
11576
11577 OLDIFS="$IFS"
11578 cleanup_130() {
11579         trap 0
11580         IFS="$OLDIFS"
11581 }
11582
11583 test_130a() {
11584         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11585         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11586
11587         trap cleanup_130 EXIT RETURN
11588
11589         local fm_file=$DIR/$tfile
11590         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11591         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11592                 error "dd failed for $fm_file"
11593
11594         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11595         filefrag -ves $fm_file
11596         RC=$?
11597         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11598                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11599         [ $RC != 0 ] && error "filefrag $fm_file failed"
11600
11601         filefrag_op=$(filefrag -ve -k $fm_file |
11602                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11603         lun=$($LFS getstripe -i $fm_file)
11604
11605         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11606         IFS=$'\n'
11607         tot_len=0
11608         for line in $filefrag_op
11609         do
11610                 frag_lun=`echo $line | cut -d: -f5`
11611                 ext_len=`echo $line | cut -d: -f4`
11612                 if (( $frag_lun != $lun )); then
11613                         cleanup_130
11614                         error "FIEMAP on 1-stripe file($fm_file) failed"
11615                         return
11616                 fi
11617                 (( tot_len += ext_len ))
11618         done
11619
11620         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11621                 cleanup_130
11622                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11623                 return
11624         fi
11625
11626         cleanup_130
11627
11628         echo "FIEMAP on single striped file succeeded"
11629 }
11630 run_test 130a "FIEMAP (1-stripe file)"
11631
11632 test_130b() {
11633         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11634
11635         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11636         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11637
11638         trap cleanup_130 EXIT RETURN
11639
11640         local fm_file=$DIR/$tfile
11641         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11642                         error "setstripe on $fm_file"
11643         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11644                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11645
11646         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11647                 error "dd failed on $fm_file"
11648
11649         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11650         filefrag_op=$(filefrag -ve -k $fm_file |
11651                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11652
11653         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11654                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11655
11656         IFS=$'\n'
11657         tot_len=0
11658         num_luns=1
11659         for line in $filefrag_op
11660         do
11661                 frag_lun=$(echo $line | cut -d: -f5 |
11662                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11663                 ext_len=$(echo $line | cut -d: -f4)
11664                 if (( $frag_lun != $last_lun )); then
11665                         if (( tot_len != 1024 )); then
11666                                 cleanup_130
11667                                 error "FIEMAP on $fm_file failed; returned " \
11668                                 "len $tot_len for OST $last_lun instead of 1024"
11669                                 return
11670                         else
11671                                 (( num_luns += 1 ))
11672                                 tot_len=0
11673                         fi
11674                 fi
11675                 (( tot_len += ext_len ))
11676                 last_lun=$frag_lun
11677         done
11678         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11679                 cleanup_130
11680                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11681                         "luns or wrong len for OST $last_lun"
11682                 return
11683         fi
11684
11685         cleanup_130
11686
11687         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11688 }
11689 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11690
11691 test_130c() {
11692         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11693
11694         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11695         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11696
11697         trap cleanup_130 EXIT RETURN
11698
11699         local fm_file=$DIR/$tfile
11700         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11701         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11702                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11703
11704         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11705                         error "dd failed on $fm_file"
11706
11707         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11708         filefrag_op=$(filefrag -ve -k $fm_file |
11709                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11710
11711         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11712                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11713
11714         IFS=$'\n'
11715         tot_len=0
11716         num_luns=1
11717         for line in $filefrag_op
11718         do
11719                 frag_lun=$(echo $line | cut -d: -f5 |
11720                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11721                 ext_len=$(echo $line | cut -d: -f4)
11722                 if (( $frag_lun != $last_lun )); then
11723                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11724                         if (( logical != 512 )); then
11725                                 cleanup_130
11726                                 error "FIEMAP on $fm_file failed; returned " \
11727                                 "logical start for lun $logical instead of 512"
11728                                 return
11729                         fi
11730                         if (( tot_len != 512 )); then
11731                                 cleanup_130
11732                                 error "FIEMAP on $fm_file failed; returned " \
11733                                 "len $tot_len for OST $last_lun instead of 1024"
11734                                 return
11735                         else
11736                                 (( num_luns += 1 ))
11737                                 tot_len=0
11738                         fi
11739                 fi
11740                 (( tot_len += ext_len ))
11741                 last_lun=$frag_lun
11742         done
11743         if (( num_luns != 2 || tot_len != 512 )); then
11744                 cleanup_130
11745                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11746                         "luns or wrong len for OST $last_lun"
11747                 return
11748         fi
11749
11750         cleanup_130
11751
11752         echo "FIEMAP on 2-stripe file with hole succeeded"
11753 }
11754 run_test 130c "FIEMAP (2-stripe file with hole)"
11755
11756 test_130d() {
11757         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11758
11759         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11760         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11761
11762         trap cleanup_130 EXIT RETURN
11763
11764         local fm_file=$DIR/$tfile
11765         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11766                         error "setstripe on $fm_file"
11767         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11768                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11769
11770         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11771         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11772                 error "dd failed on $fm_file"
11773
11774         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11775         filefrag_op=$(filefrag -ve -k $fm_file |
11776                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11777
11778         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11779                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11780
11781         IFS=$'\n'
11782         tot_len=0
11783         num_luns=1
11784         for line in $filefrag_op
11785         do
11786                 frag_lun=$(echo $line | cut -d: -f5 |
11787                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11788                 ext_len=$(echo $line | cut -d: -f4)
11789                 if (( $frag_lun != $last_lun )); then
11790                         if (( tot_len != 1024 )); then
11791                                 cleanup_130
11792                                 error "FIEMAP on $fm_file failed; returned " \
11793                                 "len $tot_len for OST $last_lun instead of 1024"
11794                                 return
11795                         else
11796                                 (( num_luns += 1 ))
11797                                 tot_len=0
11798                         fi
11799                 fi
11800                 (( tot_len += ext_len ))
11801                 last_lun=$frag_lun
11802         done
11803         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11804                 cleanup_130
11805                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11806                         "luns or wrong len for OST $last_lun"
11807                 return
11808         fi
11809
11810         cleanup_130
11811
11812         echo "FIEMAP on N-stripe file succeeded"
11813 }
11814 run_test 130d "FIEMAP (N-stripe file)"
11815
11816 test_130e() {
11817         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11818
11819         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11820         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11821
11822         trap cleanup_130 EXIT RETURN
11823
11824         local fm_file=$DIR/$tfile
11825         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11826         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11827                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11828
11829         NUM_BLKS=512
11830         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11831         for ((i = 0; i < $NUM_BLKS; i++))
11832         do
11833                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11834         done
11835
11836         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11837         filefrag_op=$(filefrag -ve -k $fm_file |
11838                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11839
11840         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11841                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11842
11843         IFS=$'\n'
11844         tot_len=0
11845         num_luns=1
11846         for line in $filefrag_op
11847         do
11848                 frag_lun=$(echo $line | cut -d: -f5 |
11849                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11850                 ext_len=$(echo $line | cut -d: -f4)
11851                 if (( $frag_lun != $last_lun )); then
11852                         if (( tot_len != $EXPECTED_LEN )); then
11853                                 cleanup_130
11854                                 error "FIEMAP on $fm_file failed; returned " \
11855                                 "len $tot_len for OST $last_lun instead " \
11856                                 "of $EXPECTED_LEN"
11857                                 return
11858                         else
11859                                 (( num_luns += 1 ))
11860                                 tot_len=0
11861                         fi
11862                 fi
11863                 (( tot_len += ext_len ))
11864                 last_lun=$frag_lun
11865         done
11866         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11867                 cleanup_130
11868                 error "FIEMAP on $fm_file failed; returned wrong number " \
11869                         "of luns or wrong len for OST $last_lun"
11870                 return
11871         fi
11872
11873         cleanup_130
11874
11875         echo "FIEMAP with continuation calls succeeded"
11876 }
11877 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11878
11879 test_130f() {
11880         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11881         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11882
11883         local fm_file=$DIR/$tfile
11884         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11885                 error "multiop create with lov_delay_create on $fm_file"
11886
11887         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11888         filefrag_extents=$(filefrag -vek $fm_file |
11889                            awk '/extents? found/ { print $2 }')
11890         if [[ "$filefrag_extents" != "0" ]]; then
11891                 error "FIEMAP on $fm_file failed; " \
11892                       "returned $filefrag_extents expected 0"
11893         fi
11894
11895         rm -f $fm_file
11896 }
11897 run_test 130f "FIEMAP (unstriped file)"
11898
11899 # Test for writev/readv
11900 test_131a() {
11901         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11902                 error "writev test failed"
11903         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11904                 error "readv failed"
11905         rm -f $DIR/$tfile
11906 }
11907 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11908
11909 test_131b() {
11910         local fsize=$((524288 + 1048576 + 1572864))
11911         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11912                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11913                         error "append writev test failed"
11914
11915         ((fsize += 1572864 + 1048576))
11916         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11917                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11918                         error "append writev test failed"
11919         rm -f $DIR/$tfile
11920 }
11921 run_test 131b "test append writev"
11922
11923 test_131c() {
11924         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11925         error "NOT PASS"
11926 }
11927 run_test 131c "test read/write on file w/o objects"
11928
11929 test_131d() {
11930         rwv -f $DIR/$tfile -w -n 1 1572864
11931         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11932         if [ "$NOB" != 1572864 ]; then
11933                 error "Short read filed: read $NOB bytes instead of 1572864"
11934         fi
11935         rm -f $DIR/$tfile
11936 }
11937 run_test 131d "test short read"
11938
11939 test_131e() {
11940         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11941         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11942         error "read hitting hole failed"
11943         rm -f $DIR/$tfile
11944 }
11945 run_test 131e "test read hitting hole"
11946
11947 check_stats() {
11948         local facet=$1
11949         local op=$2
11950         local want=${3:-0}
11951         local res
11952
11953         case $facet in
11954         mds*) res=$(do_facet $facet \
11955                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11956                  ;;
11957         ost*) res=$(do_facet $facet \
11958                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11959                  ;;
11960         *) error "Wrong facet '$facet'" ;;
11961         esac
11962         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11963         # if the argument $3 is zero, it means any stat increment is ok.
11964         if [[ $want -gt 0 ]]; then
11965                 local count=$(echo $res | awk '{ print $2 }')
11966                 [[ $count -ne $want ]] &&
11967                         error "The $op counter on $facet is $count, not $want"
11968         fi
11969 }
11970
11971 test_133a() {
11972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11973         remote_ost_nodsh && skip "remote OST with nodsh"
11974         remote_mds_nodsh && skip "remote MDS with nodsh"
11975         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11976                 skip_env "MDS doesn't support rename stats"
11977
11978         local testdir=$DIR/${tdir}/stats_testdir
11979
11980         mkdir -p $DIR/${tdir}
11981
11982         # clear stats.
11983         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11984         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11985
11986         # verify mdt stats first.
11987         mkdir ${testdir} || error "mkdir failed"
11988         check_stats $SINGLEMDS "mkdir" 1
11989         touch ${testdir}/${tfile} || error "touch failed"
11990         check_stats $SINGLEMDS "open" 1
11991         check_stats $SINGLEMDS "close" 1
11992         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11993                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11994                 check_stats $SINGLEMDS "mknod" 2
11995         }
11996         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11997         check_stats $SINGLEMDS "unlink" 1
11998         rm -f ${testdir}/${tfile} || error "file remove failed"
11999         check_stats $SINGLEMDS "unlink" 2
12000
12001         # remove working dir and check mdt stats again.
12002         rmdir ${testdir} || error "rmdir failed"
12003         check_stats $SINGLEMDS "rmdir" 1
12004
12005         local testdir1=$DIR/${tdir}/stats_testdir1
12006         mkdir -p ${testdir}
12007         mkdir -p ${testdir1}
12008         touch ${testdir1}/test1
12009         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
12010         check_stats $SINGLEMDS "crossdir_rename" 1
12011
12012         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
12013         check_stats $SINGLEMDS "samedir_rename" 1
12014
12015         rm -rf $DIR/${tdir}
12016 }
12017 run_test 133a "Verifying MDT stats ========================================"
12018
12019 test_133b() {
12020         local res
12021
12022         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12023         remote_ost_nodsh && skip "remote OST with nodsh"
12024         remote_mds_nodsh && skip "remote MDS with nodsh"
12025
12026         local testdir=$DIR/${tdir}/stats_testdir
12027
12028         mkdir -p ${testdir} || error "mkdir failed"
12029         touch ${testdir}/${tfile} || error "touch failed"
12030         cancel_lru_locks mdc
12031
12032         # clear stats.
12033         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12034         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12035
12036         # extra mdt stats verification.
12037         chmod 444 ${testdir}/${tfile} || error "chmod failed"
12038         check_stats $SINGLEMDS "setattr" 1
12039         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12040         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
12041         then            # LU-1740
12042                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
12043                 check_stats $SINGLEMDS "getattr" 1
12044         fi
12045         rm -rf $DIR/${tdir}
12046
12047         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
12048         # so the check below is not reliable
12049         [ $MDSCOUNT -eq 1 ] || return 0
12050
12051         # Sleep to avoid a cached response.
12052         #define OBD_STATFS_CACHE_SECONDS 1
12053         sleep 2
12054         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12055         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12056         $LFS df || error "lfs failed"
12057         check_stats $SINGLEMDS "statfs" 1
12058
12059         # check aggregated statfs (LU-10018)
12060         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
12061                 return 0
12062         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
12063                 return 0
12064         sleep 2
12065         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12066         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
12067         df $DIR
12068         check_stats $SINGLEMDS "statfs" 1
12069
12070         # We want to check that the client didn't send OST_STATFS to
12071         # ost1 but the MDT also uses OST_STATFS for precreate. So some
12072         # extra care is needed here.
12073         if remote_mds; then
12074                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
12075                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
12076
12077                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
12078                 [ "$res" ] && error "OST got STATFS"
12079         fi
12080
12081         return 0
12082 }
12083 run_test 133b "Verifying extra MDT stats =================================="
12084
12085 test_133c() {
12086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12087         remote_ost_nodsh && skip "remote OST with nodsh"
12088         remote_mds_nodsh && skip "remote MDS with nodsh"
12089
12090         local testdir=$DIR/$tdir/stats_testdir
12091
12092         test_mkdir -p $testdir
12093
12094         # verify obdfilter stats.
12095         $LFS setstripe -c 1 -i 0 $testdir/$tfile
12096         sync
12097         cancel_lru_locks osc
12098         wait_delete_completed
12099
12100         # clear stats.
12101         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
12102         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
12103
12104         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
12105                 error "dd failed"
12106         sync
12107         cancel_lru_locks osc
12108         check_stats ost1 "write" 1
12109
12110         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
12111         check_stats ost1 "read" 1
12112
12113         > $testdir/$tfile || error "truncate failed"
12114         check_stats ost1 "punch" 1
12115
12116         rm -f $testdir/$tfile || error "file remove failed"
12117         wait_delete_completed
12118         check_stats ost1 "destroy" 1
12119
12120         rm -rf $DIR/$tdir
12121 }
12122 run_test 133c "Verifying OST stats ========================================"
12123
12124 order_2() {
12125         local value=$1
12126         local orig=$value
12127         local order=1
12128
12129         while [ $value -ge 2 ]; do
12130                 order=$((order*2))
12131                 value=$((value/2))
12132         done
12133
12134         if [ $orig -gt $order ]; then
12135                 order=$((order*2))
12136         fi
12137         echo $order
12138 }
12139
12140 size_in_KMGT() {
12141     local value=$1
12142     local size=('K' 'M' 'G' 'T');
12143     local i=0
12144     local size_string=$value
12145
12146     while [ $value -ge 1024 ]; do
12147         if [ $i -gt 3 ]; then
12148             #T is the biggest unit we get here, if that is bigger,
12149             #just return XXXT
12150             size_string=${value}T
12151             break
12152         fi
12153         value=$((value >> 10))
12154         if [ $value -lt 1024 ]; then
12155             size_string=${value}${size[$i]}
12156             break
12157         fi
12158         i=$((i + 1))
12159     done
12160
12161     echo $size_string
12162 }
12163
12164 get_rename_size() {
12165         local size=$1
12166         local context=${2:-.}
12167         local sample=$(do_facet $SINGLEMDS $LCTL \
12168                 get_param mdt.$FSNAME-MDT0000.rename_stats |
12169                 grep -A1 $context |
12170                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
12171         echo $sample
12172 }
12173
12174 test_133d() {
12175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12176         remote_ost_nodsh && skip "remote OST with nodsh"
12177         remote_mds_nodsh && skip "remote MDS with nodsh"
12178         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
12179                 skip_env "MDS doesn't support rename stats"
12180
12181         local testdir1=$DIR/${tdir}/stats_testdir1
12182         local testdir2=$DIR/${tdir}/stats_testdir2
12183         mkdir -p $DIR/${tdir}
12184
12185         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12186
12187         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12188         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12189
12190         createmany -o $testdir1/test 512 || error "createmany failed"
12191
12192         # check samedir rename size
12193         mv ${testdir1}/test0 ${testdir1}/test_0
12194
12195         local testdir1_size=$(ls -l $DIR/${tdir} |
12196                 awk '/stats_testdir1/ {print $5}')
12197         local testdir2_size=$(ls -l $DIR/${tdir} |
12198                 awk '/stats_testdir2/ {print $5}')
12199
12200         testdir1_size=$(order_2 $testdir1_size)
12201         testdir2_size=$(order_2 $testdir2_size)
12202
12203         testdir1_size=$(size_in_KMGT $testdir1_size)
12204         testdir2_size=$(size_in_KMGT $testdir2_size)
12205
12206         echo "source rename dir size: ${testdir1_size}"
12207         echo "target rename dir size: ${testdir2_size}"
12208
12209         local cmd="do_facet $SINGLEMDS $LCTL "
12210         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12211
12212         eval $cmd || error "$cmd failed"
12213         local samedir=$($cmd | grep 'same_dir')
12214         local same_sample=$(get_rename_size $testdir1_size)
12215         [ -z "$samedir" ] && error "samedir_rename_size count error"
12216         [[ $same_sample -eq 1 ]] ||
12217                 error "samedir_rename_size error $same_sample"
12218         echo "Check same dir rename stats success"
12219
12220         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12221
12222         # check crossdir rename size
12223         mv ${testdir1}/test_0 ${testdir2}/test_0
12224
12225         testdir1_size=$(ls -l $DIR/${tdir} |
12226                 awk '/stats_testdir1/ {print $5}')
12227         testdir2_size=$(ls -l $DIR/${tdir} |
12228                 awk '/stats_testdir2/ {print $5}')
12229
12230         testdir1_size=$(order_2 $testdir1_size)
12231         testdir2_size=$(order_2 $testdir2_size)
12232
12233         testdir1_size=$(size_in_KMGT $testdir1_size)
12234         testdir2_size=$(size_in_KMGT $testdir2_size)
12235
12236         echo "source rename dir size: ${testdir1_size}"
12237         echo "target rename dir size: ${testdir2_size}"
12238
12239         eval $cmd || error "$cmd failed"
12240         local crossdir=$($cmd | grep 'crossdir')
12241         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12242         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12243         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12244         [[ $src_sample -eq 1 ]] ||
12245                 error "crossdir_rename_size error $src_sample"
12246         [[ $tgt_sample -eq 1 ]] ||
12247                 error "crossdir_rename_size error $tgt_sample"
12248         echo "Check cross dir rename stats success"
12249         rm -rf $DIR/${tdir}
12250 }
12251 run_test 133d "Verifying rename_stats ========================================"
12252
12253 test_133e() {
12254         remote_mds_nodsh && skip "remote MDS with nodsh"
12255         remote_ost_nodsh && skip "remote OST with nodsh"
12256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12257
12258         local testdir=$DIR/${tdir}/stats_testdir
12259         local ctr f0 f1 bs=32768 count=42 sum
12260
12261         mkdir -p ${testdir} || error "mkdir failed"
12262
12263         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12264
12265         for ctr in {write,read}_bytes; do
12266                 sync
12267                 cancel_lru_locks osc
12268
12269                 do_facet ost1 $LCTL set_param -n \
12270                         "obdfilter.*.exports.clear=clear"
12271
12272                 if [ $ctr = write_bytes ]; then
12273                         f0=/dev/zero
12274                         f1=${testdir}/${tfile}
12275                 else
12276                         f0=${testdir}/${tfile}
12277                         f1=/dev/null
12278                 fi
12279
12280                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12281                         error "dd failed"
12282                 sync
12283                 cancel_lru_locks osc
12284
12285                 sum=$(do_facet ost1 $LCTL get_param \
12286                         "obdfilter.*.exports.*.stats" |
12287                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12288                                 $1 == ctr { sum += $7 }
12289                                 END { printf("%0.0f", sum) }')
12290
12291                 if ((sum != bs * count)); then
12292                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12293                 fi
12294         done
12295
12296         rm -rf $DIR/${tdir}
12297 }
12298 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12299
12300 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12301
12302 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12303 # not honor the -ignore_readdir_race option correctly. So we call
12304 # error_ignore() rather than error() in these cases. See LU-11152.
12305 error_133() {
12306         if (find --version; do_facet mds1 find --version) |
12307                 grep -q '\b4\.5\.1[1-4]\b'; then
12308                 error_ignore LU-11152 "$@"
12309         else
12310                 error "$@"
12311         fi
12312 }
12313
12314 test_133f() {
12315         # First without trusting modes.
12316         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12317         echo "proc_dirs='$proc_dirs'"
12318         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12319         find $proc_dirs -exec cat '{}' \; &> /dev/null
12320
12321         # Second verifying readability.
12322         $LCTL get_param -R '*' &> /dev/null
12323
12324         # Verifing writability with badarea_io.
12325         find $proc_dirs \
12326                 -ignore_readdir_race \
12327                 -type f \
12328                 -not -name force_lbug \
12329                 -not -name changelog_mask \
12330                 -exec badarea_io '{}' \; ||
12331                         error_133 "find $proc_dirs failed"
12332 }
12333 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12334
12335 test_133g() {
12336         remote_mds_nodsh && skip "remote MDS with nodsh"
12337         remote_ost_nodsh && skip "remote OST with nodsh"
12338
12339         # eventually, this can also be replaced with "lctl get_param -R",
12340         # but not until that option is always available on the server
12341         local facet
12342         for facet in mds1 ost1; do
12343                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12344                         skip_noexit "Too old lustre on $facet"
12345                 local facet_proc_dirs=$(do_facet $facet \
12346                                         \\\ls -d $proc_regexp 2>/dev/null)
12347                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12348                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12349                 do_facet $facet find $facet_proc_dirs \
12350                         ! -name req_history \
12351                         -exec cat '{}' \\\; &> /dev/null
12352
12353                 do_facet $facet find $facet_proc_dirs \
12354                         ! -name req_history \
12355                         -type f \
12356                         -exec cat '{}' \\\; &> /dev/null ||
12357                                 error "proc file read failed"
12358
12359                 do_facet $facet find $facet_proc_dirs \
12360                         -ignore_readdir_race \
12361                         -type f \
12362                         -not -name force_lbug \
12363                         -not -name changelog_mask \
12364                         -exec badarea_io '{}' \\\; ||
12365                                 error_133 "$facet find $facet_proc_dirs failed"
12366         done
12367
12368         # remount the FS in case writes/reads /proc break the FS
12369         cleanup || error "failed to unmount"
12370         setup || error "failed to setup"
12371         true
12372 }
12373 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12374
12375 test_133h() {
12376         remote_mds_nodsh && skip "remote MDS with nodsh"
12377         remote_ost_nodsh && skip "remote OST with nodsh"
12378         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12379                 skip "Need MDS version at least 2.9.54"
12380
12381         local facet
12382
12383         for facet in client mds1 ost1; do
12384                 local facet_proc_dirs=$(do_facet $facet \
12385                                         \\\ls -d $proc_regexp 2> /dev/null)
12386                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12387                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12388                 # Get the list of files that are missing the terminating newline
12389                 local missing=($(do_facet $facet \
12390                         find ${facet_proc_dirs} -type f \|              \
12391                                 while read F\; do                       \
12392                                         awk -v FS='\v' -v RS='\v\v'     \
12393                                         "'END { if(NR>0 &&              \
12394                                         \\\$NF !~ /.*\\\n\$/)           \
12395                                                 print FILENAME}'"       \
12396                                         '\$F'\;                         \
12397                                 done 2>/dev/null))
12398                 [ ${#missing[*]} -eq 0 ] ||
12399                         error "files do not end with newline: ${missing[*]}"
12400         done
12401 }
12402 run_test 133h "Proc files should end with newlines"
12403
12404 test_134a() {
12405         remote_mds_nodsh && skip "remote MDS with nodsh"
12406         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12407                 skip "Need MDS version at least 2.7.54"
12408
12409         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12410         cancel_lru_locks mdc
12411
12412         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12413         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12414         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12415
12416         local nr=1000
12417         createmany -o $DIR/$tdir/f $nr ||
12418                 error "failed to create $nr files in $DIR/$tdir"
12419         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12420
12421         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12422         do_facet mds1 $LCTL set_param fail_loc=0x327
12423         do_facet mds1 $LCTL set_param fail_val=500
12424         touch $DIR/$tdir/m
12425
12426         echo "sleep 10 seconds ..."
12427         sleep 10
12428         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12429
12430         do_facet mds1 $LCTL set_param fail_loc=0
12431         do_facet mds1 $LCTL set_param fail_val=0
12432         [ $lck_cnt -lt $unused ] ||
12433                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12434
12435         rm $DIR/$tdir/m
12436         unlinkmany $DIR/$tdir/f $nr
12437 }
12438 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12439
12440 test_134b() {
12441         remote_mds_nodsh && skip "remote MDS with nodsh"
12442         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12443                 skip "Need MDS version at least 2.7.54"
12444
12445         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12446         cancel_lru_locks mdc
12447
12448         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12449                         ldlm.lock_reclaim_threshold_mb)
12450         # disable reclaim temporarily
12451         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12452
12453         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12454         do_facet mds1 $LCTL set_param fail_loc=0x328
12455         do_facet mds1 $LCTL set_param fail_val=500
12456
12457         $LCTL set_param debug=+trace
12458
12459         local nr=600
12460         createmany -o $DIR/$tdir/f $nr &
12461         local create_pid=$!
12462
12463         echo "Sleep $TIMEOUT seconds ..."
12464         sleep $TIMEOUT
12465         if ! ps -p $create_pid  > /dev/null 2>&1; then
12466                 do_facet mds1 $LCTL set_param fail_loc=0
12467                 do_facet mds1 $LCTL set_param fail_val=0
12468                 do_facet mds1 $LCTL set_param \
12469                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12470                 error "createmany finished incorrectly!"
12471         fi
12472         do_facet mds1 $LCTL set_param fail_loc=0
12473         do_facet mds1 $LCTL set_param fail_val=0
12474         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12475         wait $create_pid || return 1
12476
12477         unlinkmany $DIR/$tdir/f $nr
12478 }
12479 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12480
12481 test_140() { #bug-17379
12482         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12483
12484         test_mkdir $DIR/$tdir
12485         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12486         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12487
12488         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12489         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12490         local i=0
12491         while i=$((i + 1)); do
12492                 test_mkdir $i
12493                 cd $i || error "Changing to $i"
12494                 ln -s ../stat stat || error "Creating stat symlink"
12495                 # Read the symlink until ELOOP present,
12496                 # not LBUGing the system is considered success,
12497                 # we didn't overrun the stack.
12498                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12499                 if [ $ret -ne 0 ]; then
12500                         if [ $ret -eq 40 ]; then
12501                                 break  # -ELOOP
12502                         else
12503                                 error "Open stat symlink"
12504                                         return
12505                         fi
12506                 fi
12507         done
12508         i=$((i - 1))
12509         echo "The symlink depth = $i"
12510         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12511                 error "Invalid symlink depth"
12512
12513         # Test recursive symlink
12514         ln -s symlink_self symlink_self
12515         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12516         echo "open symlink_self returns $ret"
12517         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12518 }
12519 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12520
12521 test_150() {
12522         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12523
12524         local TF="$TMP/$tfile"
12525
12526         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12527         cp $TF $DIR/$tfile
12528         cancel_lru_locks $OSC
12529         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12530         remount_client $MOUNT
12531         df -P $MOUNT
12532         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12533
12534         $TRUNCATE $TF 6000
12535         $TRUNCATE $DIR/$tfile 6000
12536         cancel_lru_locks $OSC
12537         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12538
12539         echo "12345" >>$TF
12540         echo "12345" >>$DIR/$tfile
12541         cancel_lru_locks $OSC
12542         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12543
12544         echo "12345" >>$TF
12545         echo "12345" >>$DIR/$tfile
12546         cancel_lru_locks $OSC
12547         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12548
12549         rm -f $TF
12550         true
12551 }
12552 run_test 150 "truncate/append tests"
12553
12554 #LU-2902 roc_hit was not able to read all values from lproc
12555 function roc_hit_init() {
12556         local list=$(comma_list $(osts_nodes))
12557         local dir=$DIR/$tdir-check
12558         local file=$dir/$tfile
12559         local BEFORE
12560         local AFTER
12561         local idx
12562
12563         test_mkdir $dir
12564         #use setstripe to do a write to every ost
12565         for i in $(seq 0 $((OSTCOUNT-1))); do
12566                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12567                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12568                 idx=$(printf %04x $i)
12569                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12570                         awk '$1 == "cache_access" {sum += $7}
12571                                 END { printf("%0.0f", sum) }')
12572
12573                 cancel_lru_locks osc
12574                 cat $file >/dev/null
12575
12576                 AFTER=$(get_osd_param $list *OST*$idx stats |
12577                         awk '$1 == "cache_access" {sum += $7}
12578                                 END { printf("%0.0f", sum) }')
12579
12580                 echo BEFORE:$BEFORE AFTER:$AFTER
12581                 if ! let "AFTER - BEFORE == 4"; then
12582                         rm -rf $dir
12583                         error "roc_hit is not safe to use"
12584                 fi
12585                 rm $file
12586         done
12587
12588         rm -rf $dir
12589 }
12590
12591 function roc_hit() {
12592         local list=$(comma_list $(osts_nodes))
12593         echo $(get_osd_param $list '' stats |
12594                 awk '$1 == "cache_hit" {sum += $7}
12595                         END { printf("%0.0f", sum) }')
12596 }
12597
12598 function set_cache() {
12599         local on=1
12600
12601         if [ "$2" == "off" ]; then
12602                 on=0;
12603         fi
12604         local list=$(comma_list $(osts_nodes))
12605         set_osd_param $list '' $1_cache_enable $on
12606
12607         cancel_lru_locks osc
12608 }
12609
12610 test_151() {
12611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12612         remote_ost_nodsh && skip "remote OST with nodsh"
12613
12614         local CPAGES=3
12615         local list=$(comma_list $(osts_nodes))
12616
12617         # check whether obdfilter is cache capable at all
12618         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12619                 skip "not cache-capable obdfilter"
12620         fi
12621
12622         # check cache is enabled on all obdfilters
12623         if get_osd_param $list '' read_cache_enable | grep 0; then
12624                 skip "oss cache is disabled"
12625         fi
12626
12627         set_osd_param $list '' writethrough_cache_enable 1
12628
12629         # check write cache is enabled on all obdfilters
12630         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12631                 skip "oss write cache is NOT enabled"
12632         fi
12633
12634         roc_hit_init
12635
12636         #define OBD_FAIL_OBD_NO_LRU  0x609
12637         do_nodes $list $LCTL set_param fail_loc=0x609
12638
12639         # pages should be in the case right after write
12640         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12641                 error "dd failed"
12642
12643         local BEFORE=$(roc_hit)
12644         cancel_lru_locks osc
12645         cat $DIR/$tfile >/dev/null
12646         local AFTER=$(roc_hit)
12647
12648         do_nodes $list $LCTL set_param fail_loc=0
12649
12650         if ! let "AFTER - BEFORE == CPAGES"; then
12651                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12652         fi
12653
12654         # the following read invalidates the cache
12655         cancel_lru_locks osc
12656         set_osd_param $list '' read_cache_enable 0
12657         cat $DIR/$tfile >/dev/null
12658
12659         # now data shouldn't be found in the cache
12660         BEFORE=$(roc_hit)
12661         cancel_lru_locks osc
12662         cat $DIR/$tfile >/dev/null
12663         AFTER=$(roc_hit)
12664         if let "AFTER - BEFORE != 0"; then
12665                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12666         fi
12667
12668         set_osd_param $list '' read_cache_enable 1
12669         rm -f $DIR/$tfile
12670 }
12671 run_test 151 "test cache on oss and controls ==============================="
12672
12673 test_152() {
12674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12675
12676         local TF="$TMP/$tfile"
12677
12678         # simulate ENOMEM during write
12679 #define OBD_FAIL_OST_NOMEM      0x226
12680         lctl set_param fail_loc=0x80000226
12681         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12682         cp $TF $DIR/$tfile
12683         sync || error "sync failed"
12684         lctl set_param fail_loc=0
12685
12686         # discard client's cache
12687         cancel_lru_locks osc
12688
12689         # simulate ENOMEM during read
12690         lctl set_param fail_loc=0x80000226
12691         cmp $TF $DIR/$tfile || error "cmp failed"
12692         lctl set_param fail_loc=0
12693
12694         rm -f $TF
12695 }
12696 run_test 152 "test read/write with enomem ============================"
12697
12698 test_153() {
12699         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12700 }
12701 run_test 153 "test if fdatasync does not crash ======================="
12702
12703 dot_lustre_fid_permission_check() {
12704         local fid=$1
12705         local ffid=$MOUNT/.lustre/fid/$fid
12706         local test_dir=$2
12707
12708         echo "stat fid $fid"
12709         stat $ffid > /dev/null || error "stat $ffid failed."
12710         echo "touch fid $fid"
12711         touch $ffid || error "touch $ffid failed."
12712         echo "write to fid $fid"
12713         cat /etc/hosts > $ffid || error "write $ffid failed."
12714         echo "read fid $fid"
12715         diff /etc/hosts $ffid || error "read $ffid failed."
12716         echo "append write to fid $fid"
12717         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12718         echo "rename fid $fid"
12719         mv $ffid $test_dir/$tfile.1 &&
12720                 error "rename $ffid to $tfile.1 should fail."
12721         touch $test_dir/$tfile.1
12722         mv $test_dir/$tfile.1 $ffid &&
12723                 error "rename $tfile.1 to $ffid should fail."
12724         rm -f $test_dir/$tfile.1
12725         echo "truncate fid $fid"
12726         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12727         echo "link fid $fid"
12728         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12729         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12730                 echo "setfacl fid $fid"
12731                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12732                 echo "getfacl fid $fid"
12733                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12734         fi
12735         echo "unlink fid $fid"
12736         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12737         echo "mknod fid $fid"
12738         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12739
12740         fid=[0xf00000400:0x1:0x0]
12741         ffid=$MOUNT/.lustre/fid/$fid
12742
12743         echo "stat non-exist fid $fid"
12744         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12745         echo "write to non-exist fid $fid"
12746         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12747         echo "link new fid $fid"
12748         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12749
12750         mkdir -p $test_dir/$tdir
12751         touch $test_dir/$tdir/$tfile
12752         fid=$($LFS path2fid $test_dir/$tdir)
12753         rc=$?
12754         [ $rc -ne 0 ] &&
12755                 error "error: could not get fid for $test_dir/$dir/$tfile."
12756
12757         ffid=$MOUNT/.lustre/fid/$fid
12758
12759         echo "ls $fid"
12760         ls $ffid > /dev/null || error "ls $ffid failed."
12761         echo "touch $fid/$tfile.1"
12762         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12763
12764         echo "touch $MOUNT/.lustre/fid/$tfile"
12765         touch $MOUNT/.lustre/fid/$tfile && \
12766                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12767
12768         echo "setxattr to $MOUNT/.lustre/fid"
12769         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12770
12771         echo "listxattr for $MOUNT/.lustre/fid"
12772         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12773
12774         echo "delxattr from $MOUNT/.lustre/fid"
12775         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12776
12777         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12778         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12779                 error "touch invalid fid should fail."
12780
12781         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12782         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12783                 error "touch non-normal fid should fail."
12784
12785         echo "rename $tdir to $MOUNT/.lustre/fid"
12786         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12787                 error "rename to $MOUNT/.lustre/fid should fail."
12788
12789         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12790         then            # LU-3547
12791                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12792                 local new_obf_mode=777
12793
12794                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12795                 chmod $new_obf_mode $DIR/.lustre/fid ||
12796                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12797
12798                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12799                 [ $obf_mode -eq $new_obf_mode ] ||
12800                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12801
12802                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12803                 chmod $old_obf_mode $DIR/.lustre/fid ||
12804                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12805         fi
12806
12807         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12808         fid=$($LFS path2fid $test_dir/$tfile-2)
12809
12810         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12811         then # LU-5424
12812                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12813                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12814                         error "create lov data thru .lustre failed"
12815         fi
12816         echo "cp /etc/passwd $test_dir/$tfile-2"
12817         cp /etc/passwd $test_dir/$tfile-2 ||
12818                 error "copy to $test_dir/$tfile-2 failed."
12819         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12820         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12821                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12822
12823         rm -rf $test_dir/tfile.lnk
12824         rm -rf $test_dir/$tfile-2
12825 }
12826
12827 test_154A() {
12828         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12829                 skip "Need MDS version at least 2.4.1"
12830
12831         local tf=$DIR/$tfile
12832         touch $tf
12833
12834         local fid=$($LFS path2fid $tf)
12835         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12836
12837         # check that we get the same pathname back
12838         local found=$($LFS fid2path $MOUNT "$fid")
12839         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12840         [ "$found" == "$tf" ] ||
12841                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12842 }
12843 run_test 154A "lfs path2fid and fid2path basic checks"
12844
12845 test_154B() {
12846         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12847                 skip "Need MDS version at least 2.4.1"
12848
12849         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12850         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12851         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12852         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12853
12854         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12855         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12856
12857         # check that we get the same pathname
12858         echo "PFID: $PFID, name: $name"
12859         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12860         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12861         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12862                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12863
12864         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12865 }
12866 run_test 154B "verify the ll_decode_linkea tool"
12867
12868 test_154a() {
12869         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12870         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12871         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12872                 skip "Need MDS version at least 2.2.51"
12873         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12874
12875         cp /etc/hosts $DIR/$tfile
12876
12877         fid=$($LFS path2fid $DIR/$tfile)
12878         rc=$?
12879         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12880
12881         dot_lustre_fid_permission_check "$fid" $DIR ||
12882                 error "dot lustre permission check $fid failed"
12883
12884         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12885
12886         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12887
12888         touch $MOUNT/.lustre/file &&
12889                 error "creation is not allowed under .lustre"
12890
12891         mkdir $MOUNT/.lustre/dir &&
12892                 error "mkdir is not allowed under .lustre"
12893
12894         rm -rf $DIR/$tfile
12895 }
12896 run_test 154a "Open-by-FID"
12897
12898 test_154b() {
12899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12900         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12901         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12902         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12903                 skip "Need MDS version at least 2.2.51"
12904
12905         local remote_dir=$DIR/$tdir/remote_dir
12906         local MDTIDX=1
12907         local rc=0
12908
12909         mkdir -p $DIR/$tdir
12910         $LFS mkdir -i $MDTIDX $remote_dir ||
12911                 error "create remote directory failed"
12912
12913         cp /etc/hosts $remote_dir/$tfile
12914
12915         fid=$($LFS path2fid $remote_dir/$tfile)
12916         rc=$?
12917         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12918
12919         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12920                 error "dot lustre permission check $fid failed"
12921         rm -rf $DIR/$tdir
12922 }
12923 run_test 154b "Open-by-FID for remote directory"
12924
12925 test_154c() {
12926         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12927                 skip "Need MDS version at least 2.4.1"
12928
12929         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12930         local FID1=$($LFS path2fid $DIR/$tfile.1)
12931         local FID2=$($LFS path2fid $DIR/$tfile.2)
12932         local FID3=$($LFS path2fid $DIR/$tfile.3)
12933
12934         local N=1
12935         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12936                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12937                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12938                 local want=FID$N
12939                 [ "$FID" = "${!want}" ] ||
12940                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12941                 N=$((N + 1))
12942         done
12943
12944         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12945         do
12946                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12947                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12948                 N=$((N + 1))
12949         done
12950 }
12951 run_test 154c "lfs path2fid and fid2path multiple arguments"
12952
12953 test_154d() {
12954         remote_mds_nodsh && skip "remote MDS with nodsh"
12955         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12956                 skip "Need MDS version at least 2.5.53"
12957
12958         if remote_mds; then
12959                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12960         else
12961                 nid="0@lo"
12962         fi
12963         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12964         local fd
12965         local cmd
12966
12967         rm -f $DIR/$tfile
12968         touch $DIR/$tfile
12969
12970         local fid=$($LFS path2fid $DIR/$tfile)
12971         # Open the file
12972         fd=$(free_fd)
12973         cmd="exec $fd<$DIR/$tfile"
12974         eval $cmd
12975         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12976         echo "$fid_list" | grep "$fid"
12977         rc=$?
12978
12979         cmd="exec $fd>/dev/null"
12980         eval $cmd
12981         if [ $rc -ne 0 ]; then
12982                 error "FID $fid not found in open files list $fid_list"
12983         fi
12984 }
12985 run_test 154d "Verify open file fid"
12986
12987 test_154e()
12988 {
12989         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12990                 skip "Need MDS version at least 2.6.50"
12991
12992         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12993                 error ".lustre returned by readdir"
12994         fi
12995 }
12996 run_test 154e ".lustre is not returned by readdir"
12997
12998 test_154f() {
12999         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13000
13001         # create parent directory on a single MDT to avoid cross-MDT hardlinks
13002         test_mkdir -p -c1 $DIR/$tdir/d
13003         # test dirs inherit from its stripe
13004         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
13005         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
13006         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
13007         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
13008         touch $DIR/f
13009
13010         # get fid of parents
13011         local FID0=$($LFS path2fid $DIR/$tdir/d)
13012         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
13013         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
13014         local FID3=$($LFS path2fid $DIR)
13015
13016         # check that path2fid --parents returns expected <parent_fid>/name
13017         # 1) test for a directory (single parent)
13018         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
13019         [ "$parent" == "$FID0/foo1" ] ||
13020                 error "expected parent: $FID0/foo1, got: $parent"
13021
13022         # 2) test for a file with nlink > 1 (multiple parents)
13023         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
13024         echo "$parent" | grep -F "$FID1/$tfile" ||
13025                 error "$FID1/$tfile not returned in parent list"
13026         echo "$parent" | grep -F "$FID2/link" ||
13027                 error "$FID2/link not returned in parent list"
13028
13029         # 3) get parent by fid
13030         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
13031         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13032         echo "$parent" | grep -F "$FID1/$tfile" ||
13033                 error "$FID1/$tfile not returned in parent list (by fid)"
13034         echo "$parent" | grep -F "$FID2/link" ||
13035                 error "$FID2/link not returned in parent list (by fid)"
13036
13037         # 4) test for entry in root directory
13038         parent=$($LFS path2fid --parents $DIR/f)
13039         echo "$parent" | grep -F "$FID3/f" ||
13040                 error "$FID3/f not returned in parent list"
13041
13042         # 5) test it on root directory
13043         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
13044                 error "$MOUNT should not have parents"
13045
13046         # enable xattr caching and check that linkea is correctly updated
13047         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
13048         save_lustre_params client "llite.*.xattr_cache" > $save
13049         lctl set_param llite.*.xattr_cache 1
13050
13051         # 6.1) linkea update on rename
13052         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
13053
13054         # get parents by fid
13055         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13056         # foo1 should no longer be returned in parent list
13057         echo "$parent" | grep -F "$FID1" &&
13058                 error "$FID1 should no longer be in parent list"
13059         # the new path should appear
13060         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
13061                 error "$FID2/$tfile.moved is not in parent list"
13062
13063         # 6.2) linkea update on unlink
13064         rm -f $DIR/$tdir/d/foo2/link
13065         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
13066         # foo2/link should no longer be returned in parent list
13067         echo "$parent" | grep -F "$FID2/link" &&
13068                 error "$FID2/link should no longer be in parent list"
13069         true
13070
13071         rm -f $DIR/f
13072         restore_lustre_params < $save
13073         rm -f $save
13074 }
13075 run_test 154f "get parent fids by reading link ea"
13076
13077 test_154g()
13078 {
13079         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
13080         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
13081            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
13082                 skip "Need MDS version at least 2.6.92"
13083
13084         mkdir -p $DIR/$tdir
13085         llapi_fid_test -d $DIR/$tdir
13086 }
13087 run_test 154g "various llapi FID tests"
13088
13089 test_155_small_load() {
13090     local temp=$TMP/$tfile
13091     local file=$DIR/$tfile
13092
13093     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
13094         error "dd of=$temp bs=6096 count=1 failed"
13095     cp $temp $file
13096     cancel_lru_locks $OSC
13097     cmp $temp $file || error "$temp $file differ"
13098
13099     $TRUNCATE $temp 6000
13100     $TRUNCATE $file 6000
13101     cmp $temp $file || error "$temp $file differ (truncate1)"
13102
13103     echo "12345" >>$temp
13104     echo "12345" >>$file
13105     cmp $temp $file || error "$temp $file differ (append1)"
13106
13107     echo "12345" >>$temp
13108     echo "12345" >>$file
13109     cmp $temp $file || error "$temp $file differ (append2)"
13110
13111     rm -f $temp $file
13112     true
13113 }
13114
13115 test_155_big_load() {
13116         remote_ost_nodsh && skip "remote OST with nodsh"
13117
13118         local temp=$TMP/$tfile
13119         local file=$DIR/$tfile
13120
13121         free_min_max
13122         local cache_size=$(do_facet ost$((MAXI+1)) \
13123                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
13124         local large_file_size=$((cache_size * 2))
13125
13126         echo "OSS cache size: $cache_size KB"
13127         echo "Large file size: $large_file_size KB"
13128
13129         [ $MAXV -le $large_file_size ] &&
13130                 skip_env "max available OST size needs > $large_file_size KB"
13131
13132         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
13133
13134         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
13135                 error "dd of=$temp bs=$large_file_size count=1k failed"
13136         cp $temp $file
13137         ls -lh $temp $file
13138         cancel_lru_locks osc
13139         cmp $temp $file || error "$temp $file differ"
13140
13141         rm -f $temp $file
13142         true
13143 }
13144
13145 save_writethrough() {
13146         local facets=$(get_facets OST)
13147
13148         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
13149 }
13150
13151 test_155a() {
13152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13153
13154         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13155
13156         save_writethrough $p
13157
13158         set_cache read on
13159         set_cache writethrough on
13160         test_155_small_load
13161         restore_lustre_params < $p
13162         rm -f $p
13163 }
13164 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
13165
13166 test_155b() {
13167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13168
13169         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13170
13171         save_writethrough $p
13172
13173         set_cache read on
13174         set_cache writethrough off
13175         test_155_small_load
13176         restore_lustre_params < $p
13177         rm -f $p
13178 }
13179 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13180
13181 test_155c() {
13182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13183
13184         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13185
13186         save_writethrough $p
13187
13188         set_cache read off
13189         set_cache writethrough on
13190         test_155_small_load
13191         restore_lustre_params < $p
13192         rm -f $p
13193 }
13194 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13195
13196 test_155d() {
13197         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13198
13199         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13200
13201         save_writethrough $p
13202
13203         set_cache read off
13204         set_cache writethrough off
13205         test_155_small_load
13206         restore_lustre_params < $p
13207         rm -f $p
13208 }
13209 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13210
13211 test_155e() {
13212         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13213
13214         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13215
13216         save_writethrough $p
13217
13218         set_cache read on
13219         set_cache writethrough on
13220         test_155_big_load
13221         restore_lustre_params < $p
13222         rm -f $p
13223 }
13224 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13225
13226 test_155f() {
13227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13228
13229         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13230
13231         save_writethrough $p
13232
13233         set_cache read on
13234         set_cache writethrough off
13235         test_155_big_load
13236         restore_lustre_params < $p
13237         rm -f $p
13238 }
13239 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13240
13241 test_155g() {
13242         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13243
13244         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13245
13246         save_writethrough $p
13247
13248         set_cache read off
13249         set_cache writethrough on
13250         test_155_big_load
13251         restore_lustre_params < $p
13252         rm -f $p
13253 }
13254 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13255
13256 test_155h() {
13257         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13258
13259         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13260
13261         save_writethrough $p
13262
13263         set_cache read off
13264         set_cache writethrough off
13265         test_155_big_load
13266         restore_lustre_params < $p
13267         rm -f $p
13268 }
13269 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13270
13271 test_156() {
13272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13273         remote_ost_nodsh && skip "remote OST with nodsh"
13274         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13275                 skip "stats not implemented on old servers"
13276         [ "$ost1_FSTYPE" = "zfs" ] &&
13277                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13278
13279         local CPAGES=3
13280         local BEFORE
13281         local AFTER
13282         local file="$DIR/$tfile"
13283         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13284
13285         save_writethrough $p
13286         roc_hit_init
13287
13288         log "Turn on read and write cache"
13289         set_cache read on
13290         set_cache writethrough on
13291
13292         log "Write data and read it back."
13293         log "Read should be satisfied from the cache."
13294         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13295         BEFORE=$(roc_hit)
13296         cancel_lru_locks osc
13297         cat $file >/dev/null
13298         AFTER=$(roc_hit)
13299         if ! let "AFTER - BEFORE == CPAGES"; then
13300                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13301         else
13302                 log "cache hits:: before: $BEFORE, after: $AFTER"
13303         fi
13304
13305         log "Read again; it should be satisfied from the cache."
13306         BEFORE=$AFTER
13307         cancel_lru_locks osc
13308         cat $file >/dev/null
13309         AFTER=$(roc_hit)
13310         if ! let "AFTER - BEFORE == CPAGES"; then
13311                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13312         else
13313                 log "cache hits:: before: $BEFORE, after: $AFTER"
13314         fi
13315
13316         log "Turn off the read cache and turn on the write cache"
13317         set_cache read off
13318         set_cache writethrough on
13319
13320         log "Read again; it should be satisfied from the cache."
13321         BEFORE=$(roc_hit)
13322         cancel_lru_locks osc
13323         cat $file >/dev/null
13324         AFTER=$(roc_hit)
13325         if ! let "AFTER - BEFORE == CPAGES"; then
13326                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13327         else
13328                 log "cache hits:: before: $BEFORE, after: $AFTER"
13329         fi
13330
13331         log "Read again; it should not be satisfied from the cache."
13332         BEFORE=$AFTER
13333         cancel_lru_locks osc
13334         cat $file >/dev/null
13335         AFTER=$(roc_hit)
13336         if ! let "AFTER - BEFORE == 0"; then
13337                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13338         else
13339                 log "cache hits:: before: $BEFORE, after: $AFTER"
13340         fi
13341
13342         log "Write data and read it back."
13343         log "Read should be satisfied from the cache."
13344         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13345         BEFORE=$(roc_hit)
13346         cancel_lru_locks osc
13347         cat $file >/dev/null
13348         AFTER=$(roc_hit)
13349         if ! let "AFTER - BEFORE == CPAGES"; then
13350                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13351         else
13352                 log "cache hits:: before: $BEFORE, after: $AFTER"
13353         fi
13354
13355         log "Read again; it should not be satisfied from the cache."
13356         BEFORE=$AFTER
13357         cancel_lru_locks osc
13358         cat $file >/dev/null
13359         AFTER=$(roc_hit)
13360         if ! let "AFTER - BEFORE == 0"; then
13361                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13362         else
13363                 log "cache hits:: before: $BEFORE, after: $AFTER"
13364         fi
13365
13366         log "Turn off read and write cache"
13367         set_cache read off
13368         set_cache writethrough off
13369
13370         log "Write data and read it back"
13371         log "It should not be satisfied from the cache."
13372         rm -f $file
13373         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13374         cancel_lru_locks osc
13375         BEFORE=$(roc_hit)
13376         cat $file >/dev/null
13377         AFTER=$(roc_hit)
13378         if ! let "AFTER - BEFORE == 0"; then
13379                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13380         else
13381                 log "cache hits:: before: $BEFORE, after: $AFTER"
13382         fi
13383
13384         log "Turn on the read cache and turn off the write cache"
13385         set_cache read on
13386         set_cache writethrough off
13387
13388         log "Write data and read it back"
13389         log "It should not be satisfied from the cache."
13390         rm -f $file
13391         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13392         BEFORE=$(roc_hit)
13393         cancel_lru_locks osc
13394         cat $file >/dev/null
13395         AFTER=$(roc_hit)
13396         if ! let "AFTER - BEFORE == 0"; then
13397                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13398         else
13399                 log "cache hits:: before: $BEFORE, after: $AFTER"
13400         fi
13401
13402         log "Read again; it should be satisfied from the cache."
13403         BEFORE=$(roc_hit)
13404         cancel_lru_locks osc
13405         cat $file >/dev/null
13406         AFTER=$(roc_hit)
13407         if ! let "AFTER - BEFORE == CPAGES"; then
13408                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13409         else
13410                 log "cache hits:: before: $BEFORE, after: $AFTER"
13411         fi
13412
13413         restore_lustre_params < $p
13414         rm -f $p $file
13415 }
13416 run_test 156 "Verification of tunables"
13417
13418 test_160a() {
13419         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13420         remote_mds_nodsh && skip "remote MDS with nodsh"
13421         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13422                 skip "Need MDS version at least 2.2.0"
13423
13424         changelog_register || error "changelog_register failed"
13425         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13426         changelog_users $SINGLEMDS | grep -q $cl_user ||
13427                 error "User $cl_user not found in changelog_users"
13428
13429         # change something
13430         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13431         changelog_clear 0 || error "changelog_clear failed"
13432         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13433         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13434         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13435         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13436         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13437         rm $DIR/$tdir/pics/desktop.jpg
13438
13439         changelog_dump | tail -10
13440
13441         echo "verifying changelog mask"
13442         changelog_chmask "-MKDIR"
13443         changelog_chmask "-CLOSE"
13444
13445         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13446         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13447
13448         changelog_chmask "+MKDIR"
13449         changelog_chmask "+CLOSE"
13450
13451         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13452         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13453
13454         changelog_dump | tail -10
13455         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13456         CLOSES=$(changelog_dump | grep -c "CLOSE")
13457         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13458         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13459
13460         # verify contents
13461         echo "verifying target fid"
13462         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13463         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13464         [ "$fidc" == "$fidf" ] ||
13465                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13466         echo "verifying parent fid"
13467         # The FID returned from the Changelog may be the directory shard on
13468         # a different MDT, and not the FID returned by path2fid on the parent.
13469         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13470         # since this is what will matter when recreating this file in the tree.
13471         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13472         local pathp=$($LFS fid2path $MOUNT "$fidp")
13473         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13474                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13475
13476         echo "getting records for $cl_user"
13477         changelog_users $SINGLEMDS
13478         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13479         local nclr=3
13480         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13481                 error "changelog_clear failed"
13482         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13483         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13484         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13485                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13486
13487         local min0_rec=$(changelog_users $SINGLEMDS |
13488                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13489         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13490                           awk '{ print $1; exit; }')
13491
13492         changelog_dump | tail -n 5
13493         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13494         [ $first_rec == $((min0_rec + 1)) ] ||
13495                 error "first index should be $min0_rec + 1 not $first_rec"
13496
13497         # LU-3446 changelog index reset on MDT restart
13498         local cur_rec1=$(changelog_users $SINGLEMDS |
13499                          awk '/^current.index:/ { print $NF }')
13500         changelog_clear 0 ||
13501                 error "clear all changelog records for $cl_user failed"
13502         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13503         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13504                 error "Fail to start $SINGLEMDS"
13505         local cur_rec2=$(changelog_users $SINGLEMDS |
13506                          awk '/^current.index:/ { print $NF }')
13507         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13508         [ $cur_rec1 == $cur_rec2 ] ||
13509                 error "current index should be $cur_rec1 not $cur_rec2"
13510
13511         echo "verifying users from this test are deregistered"
13512         changelog_deregister || error "changelog_deregister failed"
13513         changelog_users $SINGLEMDS | grep -q $cl_user &&
13514                 error "User '$cl_user' still in changelog_users"
13515
13516         # lctl get_param -n mdd.*.changelog_users
13517         # current index: 144
13518         # ID    index (idle seconds)
13519         # cl3   144 (2)
13520         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13521                 # this is the normal case where all users were deregistered
13522                 # make sure no new records are added when no users are present
13523                 local last_rec1=$(changelog_users $SINGLEMDS |
13524                                   awk '/^current.index:/ { print $NF }')
13525                 touch $DIR/$tdir/chloe
13526                 local last_rec2=$(changelog_users $SINGLEMDS |
13527                                   awk '/^current.index:/ { print $NF }')
13528                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13529                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13530         else
13531                 # any changelog users must be leftovers from a previous test
13532                 changelog_users $SINGLEMDS
13533                 echo "other changelog users; can't verify off"
13534         fi
13535 }
13536 run_test 160a "changelog sanity"
13537
13538 test_160b() { # LU-3587
13539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13540         remote_mds_nodsh && skip "remote MDS with nodsh"
13541         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13542                 skip "Need MDS version at least 2.2.0"
13543
13544         changelog_register || error "changelog_register failed"
13545         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13546         changelog_users $SINGLEMDS | grep -q $cl_user ||
13547                 error "User '$cl_user' not found in changelog_users"
13548
13549         local longname1=$(str_repeat a 255)
13550         local longname2=$(str_repeat b 255)
13551
13552         cd $DIR
13553         echo "creating very long named file"
13554         touch $longname1 || error "create of '$longname1' failed"
13555         echo "renaming very long named file"
13556         mv $longname1 $longname2
13557
13558         changelog_dump | grep RENME | tail -n 5
13559         rm -f $longname2
13560 }
13561 run_test 160b "Verify that very long rename doesn't crash in changelog"
13562
13563 test_160c() {
13564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13565         remote_mds_nodsh && skip "remote MDS with nodsh"
13566
13567         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13568                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13569                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13570                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13571
13572         local rc=0
13573
13574         # Registration step
13575         changelog_register || error "changelog_register failed"
13576
13577         rm -rf $DIR/$tdir
13578         mkdir -p $DIR/$tdir
13579         $MCREATE $DIR/$tdir/foo_160c
13580         changelog_chmask "-TRUNC"
13581         $TRUNCATE $DIR/$tdir/foo_160c 200
13582         changelog_chmask "+TRUNC"
13583         $TRUNCATE $DIR/$tdir/foo_160c 199
13584         changelog_dump | tail -n 5
13585         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13586         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13587 }
13588 run_test 160c "verify that changelog log catch the truncate event"
13589
13590 test_160d() {
13591         remote_mds_nodsh && skip "remote MDS with nodsh"
13592         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13593         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13594         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13595                 skip "Need MDS version at least 2.7.60"
13596
13597         # Registration step
13598         changelog_register || error "changelog_register failed"
13599
13600         mkdir -p $DIR/$tdir/migrate_dir
13601         changelog_clear 0 || error "changelog_clear failed"
13602
13603         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13604         changelog_dump | tail -n 5
13605         local migrates=$(changelog_dump | grep -c "MIGRT")
13606         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13607 }
13608 run_test 160d "verify that changelog log catch the migrate event"
13609
13610 test_160e() {
13611         remote_mds_nodsh && skip "remote MDS with nodsh"
13612
13613         # Create a user
13614         changelog_register || error "changelog_register failed"
13615
13616         # Delete a future user (expect fail)
13617         local MDT0=$(facet_svc $SINGLEMDS)
13618         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13619         local rc=$?
13620
13621         if [ $rc -eq 0 ]; then
13622                 error "Deleted non-existant user cl77"
13623         elif [ $rc -ne 2 ]; then
13624                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13625         fi
13626
13627         # Clear to a bad index (1 billion should be safe)
13628         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13629         rc=$?
13630
13631         if [ $rc -eq 0 ]; then
13632                 error "Successfully cleared to invalid CL index"
13633         elif [ $rc -ne 22 ]; then
13634                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13635         fi
13636 }
13637 run_test 160e "changelog negative testing (should return errors)"
13638
13639 test_160f() {
13640         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13641         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13642                 skip "Need MDS version at least 2.10.56"
13643
13644         local mdts=$(comma_list $(mdts_nodes))
13645
13646         # Create a user
13647         changelog_register || error "first changelog_register failed"
13648         changelog_register || error "second changelog_register failed"
13649         local cl_users
13650         declare -A cl_user1
13651         declare -A cl_user2
13652         local user_rec1
13653         local user_rec2
13654         local i
13655
13656         # generate some changelog records to accumulate on each MDT
13657         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13658         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13659                 error "create $DIR/$tdir/$tfile failed"
13660
13661         # check changelogs have been generated
13662         local nbcl=$(changelog_dump | wc -l)
13663         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13664
13665         for param in "changelog_max_idle_time=10" \
13666                      "changelog_gc=1" \
13667                      "changelog_min_gc_interval=2" \
13668                      "changelog_min_free_cat_entries=3"; do
13669                 local MDT0=$(facet_svc $SINGLEMDS)
13670                 local var="${param%=*}"
13671                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13672
13673                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13674                 do_nodes $mdts $LCTL set_param mdd.*.$param
13675         done
13676
13677         # force cl_user2 to be idle (1st part)
13678         sleep 9
13679
13680         # simulate changelog catalog almost full
13681         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13682         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13683
13684         for i in $(seq $MDSCOUNT); do
13685                 cl_users=(${CL_USERS[mds$i]})
13686                 cl_user1[mds$i]="${cl_users[0]}"
13687                 cl_user2[mds$i]="${cl_users[1]}"
13688
13689                 [ -n "${cl_user1[mds$i]}" ] ||
13690                         error "mds$i: no user registered"
13691                 [ -n "${cl_user2[mds$i]}" ] ||
13692                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13693
13694                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13695                 [ -n "$user_rec1" ] ||
13696                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13697                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13698                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13699                 [ -n "$user_rec2" ] ||
13700                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13701                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13702                      "$user_rec1 + 2 == $user_rec2"
13703                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13704                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13705                               "$user_rec1 + 2, but is $user_rec2"
13706                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13707                 [ -n "$user_rec2" ] ||
13708                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13709                 [ $user_rec1 == $user_rec2 ] ||
13710                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13711                               "$user_rec1, but is $user_rec2"
13712         done
13713
13714         # force cl_user2 to be idle (2nd part) and to reach
13715         # changelog_max_idle_time
13716         sleep 2
13717
13718         # generate one more changelog to trigger fail_loc
13719         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13720                 error "create $DIR/$tdir/${tfile}bis failed"
13721
13722         # ensure gc thread is done
13723         for i in $(mdts_nodes); do
13724                 wait_update $i \
13725                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13726                         error "$i: GC-thread not done"
13727         done
13728
13729         local first_rec
13730         for i in $(seq $MDSCOUNT); do
13731                 # check cl_user1 still registered
13732                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13733                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13734                 # check cl_user2 unregistered
13735                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13736                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13737
13738                 # check changelogs are present and starting at $user_rec1 + 1
13739                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13740                 [ -n "$user_rec1" ] ||
13741                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13742                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13743                             awk '{ print $1; exit; }')
13744
13745                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13746                 [ $((user_rec1 + 1)) == $first_rec ] ||
13747                         error "mds$i: first index should be $user_rec1 + 1, " \
13748                               "but is $first_rec"
13749         done
13750 }
13751 run_test 160f "changelog garbage collect (timestamped users)"
13752
13753 test_160g() {
13754         remote_mds_nodsh && skip "remote MDS with nodsh"
13755         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13756                 skip "Need MDS version at least 2.10.56"
13757
13758         local mdts=$(comma_list $(mdts_nodes))
13759
13760         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13761         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13762
13763         # Create a user
13764         changelog_register || error "first changelog_register failed"
13765         changelog_register || error "second changelog_register failed"
13766         local cl_users
13767         declare -A cl_user1
13768         declare -A cl_user2
13769         local user_rec1
13770         local user_rec2
13771         local i
13772
13773         # generate some changelog records to accumulate on each MDT
13774         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13775         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13776                 error "create $DIR/$tdir/$tfile failed"
13777
13778         # check changelogs have been generated
13779         local nbcl=$(changelog_dump | wc -l)
13780         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13781
13782         # reduce the max_idle_indexes value to make sure we exceed it
13783         max_ndx=$((nbcl / 2 - 1))
13784
13785         for param in "changelog_max_idle_indexes=$max_ndx" \
13786                      "changelog_gc=1" \
13787                      "changelog_min_gc_interval=2" \
13788                      "changelog_min_free_cat_entries=3"; do
13789                 local MDT0=$(facet_svc $SINGLEMDS)
13790                 local var="${param%=*}"
13791                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13792
13793                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13794                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13795                         error "unable to set mdd.*.$param"
13796         done
13797
13798         # simulate changelog catalog almost full
13799         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13800         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13801
13802         for i in $(seq $MDSCOUNT); do
13803                 cl_users=(${CL_USERS[mds$i]})
13804                 cl_user1[mds$i]="${cl_users[0]}"
13805                 cl_user2[mds$i]="${cl_users[1]}"
13806
13807                 [ -n "${cl_user1[mds$i]}" ] ||
13808                         error "mds$i: no user registered"
13809                 [ -n "${cl_user2[mds$i]}" ] ||
13810                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13811
13812                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13813                 [ -n "$user_rec1" ] ||
13814                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13815                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13816                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13817                 [ -n "$user_rec2" ] ||
13818                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13819                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13820                      "$user_rec1 + 2 == $user_rec2"
13821                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13822                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13823                               "$user_rec1 + 2, but is $user_rec2"
13824                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13825                 [ -n "$user_rec2" ] ||
13826                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13827                 [ $user_rec1 == $user_rec2 ] ||
13828                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13829                               "$user_rec1, but is $user_rec2"
13830         done
13831
13832         # ensure we are past the previous changelog_min_gc_interval set above
13833         sleep 2
13834
13835         # generate one more changelog to trigger fail_loc
13836         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13837                 error "create $DIR/$tdir/${tfile}bis failed"
13838
13839         # ensure gc thread is done
13840         for i in $(mdts_nodes); do
13841                 wait_update $i \
13842                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13843                         error "$i: GC-thread not done"
13844         done
13845
13846         local first_rec
13847         for i in $(seq $MDSCOUNT); do
13848                 # check cl_user1 still registered
13849                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13850                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13851                 # check cl_user2 unregistered
13852                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13853                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13854
13855                 # check changelogs are present and starting at $user_rec1 + 1
13856                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13857                 [ -n "$user_rec1" ] ||
13858                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13859                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13860                             awk '{ print $1; exit; }')
13861
13862                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13863                 [ $((user_rec1 + 1)) == $first_rec ] ||
13864                         error "mds$i: first index should be $user_rec1 + 1, " \
13865                               "but is $first_rec"
13866         done
13867 }
13868 run_test 160g "changelog garbage collect (old users)"
13869
13870 test_160h() {
13871         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13872         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13873                 skip "Need MDS version at least 2.10.56"
13874
13875         local mdts=$(comma_list $(mdts_nodes))
13876
13877         # Create a user
13878         changelog_register || error "first changelog_register failed"
13879         changelog_register || error "second changelog_register failed"
13880         local cl_users
13881         declare -A cl_user1
13882         declare -A cl_user2
13883         local user_rec1
13884         local user_rec2
13885         local i
13886
13887         # generate some changelog records to accumulate on each MDT
13888         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13889         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13890                 error "create $DIR/$tdir/$tfile failed"
13891
13892         # check changelogs have been generated
13893         local nbcl=$(changelog_dump | wc -l)
13894         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13895
13896         for param in "changelog_max_idle_time=10" \
13897                      "changelog_gc=1" \
13898                      "changelog_min_gc_interval=2"; do
13899                 local MDT0=$(facet_svc $SINGLEMDS)
13900                 local var="${param%=*}"
13901                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13902
13903                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13904                 do_nodes $mdts $LCTL set_param mdd.*.$param
13905         done
13906
13907         # force cl_user2 to be idle (1st part)
13908         sleep 9
13909
13910         for i in $(seq $MDSCOUNT); do
13911                 cl_users=(${CL_USERS[mds$i]})
13912                 cl_user1[mds$i]="${cl_users[0]}"
13913                 cl_user2[mds$i]="${cl_users[1]}"
13914
13915                 [ -n "${cl_user1[mds$i]}" ] ||
13916                         error "mds$i: no user registered"
13917                 [ -n "${cl_user2[mds$i]}" ] ||
13918                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13919
13920                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13921                 [ -n "$user_rec1" ] ||
13922                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13923                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13924                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13925                 [ -n "$user_rec2" ] ||
13926                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13927                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13928                      "$user_rec1 + 2 == $user_rec2"
13929                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13930                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13931                               "$user_rec1 + 2, but is $user_rec2"
13932                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13933                 [ -n "$user_rec2" ] ||
13934                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13935                 [ $user_rec1 == $user_rec2 ] ||
13936                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13937                               "$user_rec1, but is $user_rec2"
13938         done
13939
13940         # force cl_user2 to be idle (2nd part) and to reach
13941         # changelog_max_idle_time
13942         sleep 2
13943
13944         # force each GC-thread start and block then
13945         # one per MDT/MDD, set fail_val accordingly
13946         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13947         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13948
13949         # generate more changelogs to trigger fail_loc
13950         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13951                 error "create $DIR/$tdir/${tfile}bis failed"
13952
13953         # stop MDT to stop GC-thread, should be done in back-ground as it will
13954         # block waiting for the thread to be released and exit
13955         declare -A stop_pids
13956         for i in $(seq $MDSCOUNT); do
13957                 stop mds$i &
13958                 stop_pids[mds$i]=$!
13959         done
13960
13961         for i in $(mdts_nodes); do
13962                 local facet
13963                 local nb=0
13964                 local facets=$(facets_up_on_host $i)
13965
13966                 for facet in ${facets//,/ }; do
13967                         if [[ $facet == mds* ]]; then
13968                                 nb=$((nb + 1))
13969                         fi
13970                 done
13971                 # ensure each MDS's gc threads are still present and all in "R"
13972                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13973                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13974                         error "$i: expected $nb GC-thread"
13975                 wait_update $i \
13976                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13977                         "R" 20 ||
13978                         error "$i: GC-thread not found in R-state"
13979                 # check umounts of each MDT on MDS have reached kthread_stop()
13980                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13981                         error "$i: expected $nb umount"
13982                 wait_update $i \
13983                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13984                         error "$i: umount not found in D-state"
13985         done
13986
13987         # release all GC-threads
13988         do_nodes $mdts $LCTL set_param fail_loc=0
13989
13990         # wait for MDT stop to complete
13991         for i in $(seq $MDSCOUNT); do
13992                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13993         done
13994
13995         # XXX
13996         # may try to check if any orphan changelog records are present
13997         # via ldiskfs/zfs and llog_reader...
13998
13999         # re-start/mount MDTs
14000         for i in $(seq $MDSCOUNT); do
14001                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
14002                         error "Fail to start mds$i"
14003         done
14004
14005         local first_rec
14006         for i in $(seq $MDSCOUNT); do
14007                 # check cl_user1 still registered
14008                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
14009                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14010                 # check cl_user2 unregistered
14011                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
14012                         error "mds$i: User ${cl_user2[mds$i]} still registered"
14013
14014                 # check changelogs are present and starting at $user_rec1 + 1
14015                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
14016                 [ -n "$user_rec1" ] ||
14017                         error "mds$i: User ${cl_user1[mds$i]} not registered"
14018                 first_rec=$($LFS changelog $(facet_svc mds$i) |
14019                             awk '{ print $1; exit; }')
14020
14021                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
14022                 [ $((user_rec1 + 1)) == $first_rec ] ||
14023                         error "mds$i: first index should be $user_rec1 + 1, " \
14024                               "but is $first_rec"
14025         done
14026 }
14027 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
14028               "during mount"
14029
14030 test_160i() {
14031
14032         local mdts=$(comma_list $(mdts_nodes))
14033
14034         changelog_register || error "first changelog_register failed"
14035
14036         # generate some changelog records to accumulate on each MDT
14037         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14038         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
14039                 error "create $DIR/$tdir/$tfile failed"
14040
14041         # check changelogs have been generated
14042         local nbcl=$(changelog_dump | wc -l)
14043         [[ $nbcl -eq 0 ]] && error "no changelogs found"
14044
14045         # simulate race between register and unregister
14046         # XXX as fail_loc is set per-MDS, with DNE configs the race
14047         # simulation will only occur for one MDT per MDS and for the
14048         # others the normal race scenario will take place
14049         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
14050         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
14051         do_nodes $mdts $LCTL set_param fail_val=1
14052
14053         # unregister 1st user
14054         changelog_deregister &
14055         local pid1=$!
14056         # wait some time for deregister work to reach race rdv
14057         sleep 2
14058         # register 2nd user
14059         changelog_register || error "2nd user register failed"
14060
14061         wait $pid1 || error "1st user deregister failed"
14062
14063         local i
14064         local last_rec
14065         declare -A LAST_REC
14066         for i in $(seq $MDSCOUNT); do
14067                 if changelog_users mds$i | grep "^cl"; then
14068                         # make sure new records are added with one user present
14069                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
14070                                           awk '/^current.index:/ { print $NF }')
14071                 else
14072                         error "mds$i has no user registered"
14073                 fi
14074         done
14075
14076         # generate more changelog records to accumulate on each MDT
14077         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14078                 error "create $DIR/$tdir/${tfile}bis failed"
14079
14080         for i in $(seq $MDSCOUNT); do
14081                 last_rec=$(changelog_users $SINGLEMDS |
14082                            awk '/^current.index:/ { print $NF }')
14083                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
14084                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
14085                         error "changelogs are off on mds$i"
14086         done
14087 }
14088 run_test 160i "changelog user register/unregister race"
14089
14090 test_160j() {
14091         remote_mds_nodsh && skip "remote MDS with nodsh"
14092         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
14093                 skip "Need MDS version at least 2.12.56"
14094
14095         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
14096
14097         changelog_register || error "first changelog_register failed"
14098
14099         # generate some changelog
14100         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
14101         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
14102                 error "create $DIR/$tdir/${tfile}bis failed"
14103
14104         # open the changelog device
14105         exec 3>/dev/changelog-$FSNAME-MDT0000
14106         exec 4</dev/changelog-$FSNAME-MDT0000
14107
14108         # umount the first lustre mount
14109         umount $MOUNT
14110
14111         # read changelog
14112         cat <&4 >/dev/null || error "read changelog failed"
14113
14114         # clear changelog
14115         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14116         changelog_users $SINGLEMDS | grep -q $cl_user ||
14117                 error "User $cl_user not found in changelog_users"
14118
14119         printf 'clear:'$cl_user':0' >&3
14120
14121         # close
14122         exec 3>&-
14123         exec 4<&-
14124
14125         # cleanup
14126         changelog_deregister || error "changelog_deregister failed"
14127
14128         umount $MOUNT2
14129         mount_client $MOUNT || error "mount_client on $MOUNT failed"
14130 }
14131 run_test 160j "client can be umounted  while its chanangelog is being used"
14132
14133 test_160k() {
14134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14135         remote_mds_nodsh && skip "remote MDS with nodsh"
14136
14137         mkdir -p $DIR/$tdir/1/1
14138
14139         changelog_register || error "changelog_register failed"
14140         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
14141
14142         changelog_users $SINGLEMDS | grep -q $cl_user ||
14143                 error "User '$cl_user' not found in changelog_users"
14144 #define OBD_FAIL_MDS_CHANGELOG_REORDER 0x15d
14145         do_facet mds1 $LCTL set_param fail_loc=0x8000015d fail_val=3
14146         rmdir $DIR/$tdir/1/1 & sleep 1
14147         mkdir $DIR/$tdir/2
14148         touch $DIR/$tdir/2/2
14149         rm -rf $DIR/$tdir/2
14150
14151         wait
14152         sleep 4
14153
14154         changelog_dump | grep rmdir || error "rmdir not recorded"
14155
14156         rm -rf $DIR/$tdir
14157         changelog_deregister
14158 }
14159 run_test 160k "Verify that changelog records are not lost"
14160
14161 test_161a() {
14162         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14163
14164         test_mkdir -c1 $DIR/$tdir
14165         cp /etc/hosts $DIR/$tdir/$tfile
14166         test_mkdir -c1 $DIR/$tdir/foo1
14167         test_mkdir -c1 $DIR/$tdir/foo2
14168         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
14169         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
14170         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
14171         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
14172         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
14173         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14174                 $LFS fid2path $DIR $FID
14175                 error "bad link ea"
14176         fi
14177         # middle
14178         rm $DIR/$tdir/foo2/zachary
14179         # last
14180         rm $DIR/$tdir/foo2/thor
14181         # first
14182         rm $DIR/$tdir/$tfile
14183         # rename
14184         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
14185         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
14186                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
14187         rm $DIR/$tdir/foo2/maggie
14188
14189         # overflow the EA
14190         local longname=$tfile.avg_len_is_thirty_two_
14191         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
14192                 error_noexit 'failed to unlink many hardlinks'" EXIT
14193         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
14194                 error "failed to hardlink many files"
14195         links=$($LFS fid2path $DIR $FID | wc -l)
14196         echo -n "${links}/1000 links in link EA"
14197         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
14198 }
14199 run_test 161a "link ea sanity"
14200
14201 test_161b() {
14202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14203         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
14204
14205         local MDTIDX=1
14206         local remote_dir=$DIR/$tdir/remote_dir
14207
14208         mkdir -p $DIR/$tdir
14209         $LFS mkdir -i $MDTIDX $remote_dir ||
14210                 error "create remote directory failed"
14211
14212         cp /etc/hosts $remote_dir/$tfile
14213         mkdir -p $remote_dir/foo1
14214         mkdir -p $remote_dir/foo2
14215         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14216         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14217         ln $remote_dir/$tfile $remote_dir/foo1/luna
14218         ln $remote_dir/$tfile $remote_dir/foo2/thor
14219
14220         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14221                      tr -d ']')
14222         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14223                 $LFS fid2path $DIR $FID
14224                 error "bad link ea"
14225         fi
14226         # middle
14227         rm $remote_dir/foo2/zachary
14228         # last
14229         rm $remote_dir/foo2/thor
14230         # first
14231         rm $remote_dir/$tfile
14232         # rename
14233         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14234         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14235         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14236                 $LFS fid2path $DIR $FID
14237                 error "bad link rename"
14238         fi
14239         rm $remote_dir/foo2/maggie
14240
14241         # overflow the EA
14242         local longname=filename_avg_len_is_thirty_two_
14243         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14244                 error "failed to hardlink many files"
14245         links=$($LFS fid2path $DIR $FID | wc -l)
14246         echo -n "${links}/1000 links in link EA"
14247         [[ ${links} -gt 60 ]] ||
14248                 error "expected at least 60 links in link EA"
14249         unlinkmany $remote_dir/foo2/$longname 1000 ||
14250         error "failed to unlink many hardlinks"
14251 }
14252 run_test 161b "link ea sanity under remote directory"
14253
14254 test_161c() {
14255         remote_mds_nodsh && skip "remote MDS with nodsh"
14256         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14257         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14258                 skip "Need MDS version at least 2.1.5"
14259
14260         # define CLF_RENAME_LAST 0x0001
14261         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14262         changelog_register || error "changelog_register failed"
14263
14264         rm -rf $DIR/$tdir
14265         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14266         touch $DIR/$tdir/foo_161c
14267         touch $DIR/$tdir/bar_161c
14268         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14269         changelog_dump | grep RENME | tail -n 5
14270         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14271         changelog_clear 0 || error "changelog_clear failed"
14272         if [ x$flags != "x0x1" ]; then
14273                 error "flag $flags is not 0x1"
14274         fi
14275
14276         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14277         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14278         touch $DIR/$tdir/foo_161c
14279         touch $DIR/$tdir/bar_161c
14280         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14281         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14282         changelog_dump | grep RENME | tail -n 5
14283         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14284         changelog_clear 0 || error "changelog_clear failed"
14285         if [ x$flags != "x0x0" ]; then
14286                 error "flag $flags is not 0x0"
14287         fi
14288         echo "rename overwrite a target having nlink > 1," \
14289                 "changelog record has flags of $flags"
14290
14291         # rename doesn't overwrite a target (changelog flag 0x0)
14292         touch $DIR/$tdir/foo_161c
14293         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14294         changelog_dump | grep RENME | tail -n 5
14295         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14296         changelog_clear 0 || error "changelog_clear failed"
14297         if [ x$flags != "x0x0" ]; then
14298                 error "flag $flags is not 0x0"
14299         fi
14300         echo "rename doesn't overwrite a target," \
14301                 "changelog record has flags of $flags"
14302
14303         # define CLF_UNLINK_LAST 0x0001
14304         # unlink a file having nlink = 1 (changelog flag 0x1)
14305         rm -f $DIR/$tdir/foo2_161c
14306         changelog_dump | grep UNLNK | tail -n 5
14307         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14308         changelog_clear 0 || error "changelog_clear failed"
14309         if [ x$flags != "x0x1" ]; then
14310                 error "flag $flags is not 0x1"
14311         fi
14312         echo "unlink a file having nlink = 1," \
14313                 "changelog record has flags of $flags"
14314
14315         # unlink a file having nlink > 1 (changelog flag 0x0)
14316         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14317         rm -f $DIR/$tdir/foobar_161c
14318         changelog_dump | grep UNLNK | tail -n 5
14319         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14320         changelog_clear 0 || error "changelog_clear failed"
14321         if [ x$flags != "x0x0" ]; then
14322                 error "flag $flags is not 0x0"
14323         fi
14324         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14325 }
14326 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14327
14328 test_161d() {
14329         remote_mds_nodsh && skip "remote MDS with nodsh"
14330         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14331
14332         local pid
14333         local fid
14334
14335         changelog_register || error "changelog_register failed"
14336
14337         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14338         # interfer with $MOUNT/.lustre/fid/ access
14339         mkdir $DIR/$tdir
14340         [[ $? -eq 0 ]] || error "mkdir failed"
14341
14342         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14343         $LCTL set_param fail_loc=0x8000140c
14344         # 5s pause
14345         $LCTL set_param fail_val=5
14346
14347         # create file
14348         echo foofoo > $DIR/$tdir/$tfile &
14349         pid=$!
14350
14351         # wait for create to be delayed
14352         sleep 2
14353
14354         ps -p $pid
14355         [[ $? -eq 0 ]] || error "create should be blocked"
14356
14357         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14358         stack_trap "rm -f $tempfile"
14359         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14360         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14361         # some delay may occur during ChangeLog publishing and file read just
14362         # above, that could allow file write to happen finally
14363         [[ -s $tempfile ]] && echo "file should be empty"
14364
14365         $LCTL set_param fail_loc=0
14366
14367         wait $pid
14368         [[ $? -eq 0 ]] || error "create failed"
14369 }
14370 run_test 161d "create with concurrent .lustre/fid access"
14371
14372 check_path() {
14373         local expected="$1"
14374         shift
14375         local fid="$2"
14376
14377         local path
14378         path=$($LFS fid2path "$@")
14379         local rc=$?
14380
14381         if [ $rc -ne 0 ]; then
14382                 error "path looked up of '$expected' failed: rc=$rc"
14383         elif [ "$path" != "$expected" ]; then
14384                 error "path looked up '$path' instead of '$expected'"
14385         else
14386                 echo "FID '$fid' resolves to path '$path' as expected"
14387         fi
14388 }
14389
14390 test_162a() { # was test_162
14391         test_mkdir -p -c1 $DIR/$tdir/d2
14392         touch $DIR/$tdir/d2/$tfile
14393         touch $DIR/$tdir/d2/x1
14394         touch $DIR/$tdir/d2/x2
14395         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14396         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14397         # regular file
14398         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14399         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14400
14401         # softlink
14402         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14403         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14404         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14405
14406         # softlink to wrong file
14407         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14408         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14409         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14410
14411         # hardlink
14412         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14413         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14414         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14415         # fid2path dir/fsname should both work
14416         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14417         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14418
14419         # hardlink count: check that there are 2 links
14420         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14421         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14422
14423         # hardlink indexing: remove the first link
14424         rm $DIR/$tdir/d2/p/q/r/hlink
14425         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14426 }
14427 run_test 162a "path lookup sanity"
14428
14429 test_162b() {
14430         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14431         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14432
14433         mkdir $DIR/$tdir
14434         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14435                                 error "create striped dir failed"
14436
14437         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14438                                         tail -n 1 | awk '{print $2}')
14439         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14440
14441         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14442         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14443
14444         # regular file
14445         for ((i=0;i<5;i++)); do
14446                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14447                         error "get fid for f$i failed"
14448                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14449
14450                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14451                         error "get fid for d$i failed"
14452                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14453         done
14454
14455         return 0
14456 }
14457 run_test 162b "striped directory path lookup sanity"
14458
14459 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14460 test_162c() {
14461         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14462                 skip "Need MDS version at least 2.7.51"
14463
14464         local lpath=$tdir.local
14465         local rpath=$tdir.remote
14466
14467         test_mkdir $DIR/$lpath
14468         test_mkdir $DIR/$rpath
14469
14470         for ((i = 0; i <= 101; i++)); do
14471                 lpath="$lpath/$i"
14472                 mkdir $DIR/$lpath
14473                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14474                         error "get fid for local directory $DIR/$lpath failed"
14475                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14476
14477                 rpath="$rpath/$i"
14478                 test_mkdir $DIR/$rpath
14479                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14480                         error "get fid for remote directory $DIR/$rpath failed"
14481                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14482         done
14483
14484         return 0
14485 }
14486 run_test 162c "fid2path works with paths 100 or more directories deep"
14487
14488 test_169() {
14489         # do directio so as not to populate the page cache
14490         log "creating a 10 Mb file"
14491         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14492         log "starting reads"
14493         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14494         log "truncating the file"
14495         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14496         log "killing dd"
14497         kill %+ || true # reads might have finished
14498         echo "wait until dd is finished"
14499         wait
14500         log "removing the temporary file"
14501         rm -rf $DIR/$tfile || error "tmp file removal failed"
14502 }
14503 run_test 169 "parallel read and truncate should not deadlock"
14504
14505 test_170() {
14506         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14507
14508         $LCTL clear     # bug 18514
14509         $LCTL debug_daemon start $TMP/${tfile}_log_good
14510         touch $DIR/$tfile
14511         $LCTL debug_daemon stop
14512         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14513                 error "sed failed to read log_good"
14514
14515         $LCTL debug_daemon start $TMP/${tfile}_log_good
14516         rm -rf $DIR/$tfile
14517         $LCTL debug_daemon stop
14518
14519         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14520                error "lctl df log_bad failed"
14521
14522         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14523         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14524
14525         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14526         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14527
14528         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14529                 error "bad_line good_line1 good_line2 are empty"
14530
14531         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14532         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14533         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14534
14535         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14536         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14537         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14538
14539         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14540                 error "bad_line_new good_line_new are empty"
14541
14542         local expected_good=$((good_line1 + good_line2*2))
14543
14544         rm -f $TMP/${tfile}*
14545         # LU-231, short malformed line may not be counted into bad lines
14546         if [ $bad_line -ne $bad_line_new ] &&
14547                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14548                 error "expected $bad_line bad lines, but got $bad_line_new"
14549                 return 1
14550         fi
14551
14552         if [ $expected_good -ne $good_line_new ]; then
14553                 error "expected $expected_good good lines, but got $good_line_new"
14554                 return 2
14555         fi
14556         true
14557 }
14558 run_test 170 "test lctl df to handle corrupted log ====================="
14559
14560 test_171() { # bug20592
14561         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14562
14563         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14564         $LCTL set_param fail_loc=0x50e
14565         $LCTL set_param fail_val=3000
14566         multiop_bg_pause $DIR/$tfile O_s || true
14567         local MULTIPID=$!
14568         kill -USR1 $MULTIPID
14569         # cause log dump
14570         sleep 3
14571         wait $MULTIPID
14572         if dmesg | grep "recursive fault"; then
14573                 error "caught a recursive fault"
14574         fi
14575         $LCTL set_param fail_loc=0
14576         true
14577 }
14578 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14579
14580 # it would be good to share it with obdfilter-survey/iokit-libecho code
14581 setup_obdecho_osc () {
14582         local rc=0
14583         local ost_nid=$1
14584         local obdfilter_name=$2
14585         echo "Creating new osc for $obdfilter_name on $ost_nid"
14586         # make sure we can find loopback nid
14587         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14588
14589         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14590                            ${obdfilter_name}_osc_UUID || rc=2; }
14591         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14592                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14593         return $rc
14594 }
14595
14596 cleanup_obdecho_osc () {
14597         local obdfilter_name=$1
14598         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14599         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14600         return 0
14601 }
14602
14603 obdecho_test() {
14604         local OBD=$1
14605         local node=$2
14606         local pages=${3:-64}
14607         local rc=0
14608         local id
14609
14610         local count=10
14611         local obd_size=$(get_obd_size $node $OBD)
14612         local page_size=$(get_page_size $node)
14613         if [[ -n "$obd_size" ]]; then
14614                 local new_count=$((obd_size / (pages * page_size / 1024)))
14615                 [[ $new_count -ge $count ]] || count=$new_count
14616         fi
14617
14618         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14619         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14620                            rc=2; }
14621         if [ $rc -eq 0 ]; then
14622             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14623             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14624         fi
14625         echo "New object id is $id"
14626         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14627                            rc=4; }
14628         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14629                            "test_brw $count w v $pages $id" || rc=4; }
14630         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14631                            rc=4; }
14632         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14633                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14634         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14635                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14636         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14637         return $rc
14638 }
14639
14640 test_180a() {
14641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14642
14643         if ! module_loaded obdecho; then
14644                 load_module obdecho/obdecho &&
14645                         stack_trap "rmmod obdecho" EXIT ||
14646                         error "unable to load obdecho on client"
14647         fi
14648
14649         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14650         local host=$($LCTL get_param -n osc.$osc.import |
14651                      awk '/current_connection:/ { print $2 }' )
14652         local target=$($LCTL get_param -n osc.$osc.import |
14653                        awk '/target:/ { print $2 }' )
14654         target=${target%_UUID}
14655
14656         if [ -n "$target" ]; then
14657                 setup_obdecho_osc $host $target &&
14658                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14659                         { error "obdecho setup failed with $?"; return; }
14660
14661                 obdecho_test ${target}_osc client ||
14662                         error "obdecho_test failed on ${target}_osc"
14663         else
14664                 $LCTL get_param osc.$osc.import
14665                 error "there is no osc.$osc.import target"
14666         fi
14667 }
14668 run_test 180a "test obdecho on osc"
14669
14670 test_180b() {
14671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14672         remote_ost_nodsh && skip "remote OST with nodsh"
14673
14674         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14675                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14676                 error "failed to load module obdecho"
14677
14678         local target=$(do_facet ost1 $LCTL dl |
14679                        awk '/obdfilter/ { print $4; exit; }')
14680
14681         if [ -n "$target" ]; then
14682                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14683         else
14684                 do_facet ost1 $LCTL dl
14685                 error "there is no obdfilter target on ost1"
14686         fi
14687 }
14688 run_test 180b "test obdecho directly on obdfilter"
14689
14690 test_180c() { # LU-2598
14691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14692         remote_ost_nodsh && skip "remote OST with nodsh"
14693         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14694                 skip "Need MDS version at least 2.4.0"
14695
14696         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14697                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14698                 error "failed to load module obdecho"
14699
14700         local target=$(do_facet ost1 $LCTL dl |
14701                        awk '/obdfilter/ { print $4; exit; }')
14702
14703         if [ -n "$target" ]; then
14704                 local pages=16384 # 64MB bulk I/O RPC size
14705
14706                 obdecho_test "$target" ost1 "$pages" ||
14707                         error "obdecho_test with pages=$pages failed with $?"
14708         else
14709                 do_facet ost1 $LCTL dl
14710                 error "there is no obdfilter target on ost1"
14711         fi
14712 }
14713 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14714
14715 test_181() { # bug 22177
14716         test_mkdir $DIR/$tdir
14717         # create enough files to index the directory
14718         createmany -o $DIR/$tdir/foobar 4000
14719         # print attributes for debug purpose
14720         lsattr -d .
14721         # open dir
14722         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14723         MULTIPID=$!
14724         # remove the files & current working dir
14725         unlinkmany $DIR/$tdir/foobar 4000
14726         rmdir $DIR/$tdir
14727         kill -USR1 $MULTIPID
14728         wait $MULTIPID
14729         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14730         return 0
14731 }
14732 run_test 181 "Test open-unlinked dir ========================"
14733
14734 test_182() {
14735         local fcount=1000
14736         local tcount=10
14737
14738         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14739
14740         $LCTL set_param mdc.*.rpc_stats=clear
14741
14742         for (( i = 0; i < $tcount; i++ )) ; do
14743                 mkdir $DIR/$tdir/$i
14744         done
14745
14746         for (( i = 0; i < $tcount; i++ )) ; do
14747                 createmany -o $DIR/$tdir/$i/f- $fcount &
14748         done
14749         wait
14750
14751         for (( i = 0; i < $tcount; i++ )) ; do
14752                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14753         done
14754         wait
14755
14756         $LCTL get_param mdc.*.rpc_stats
14757
14758         rm -rf $DIR/$tdir
14759 }
14760 run_test 182 "Test parallel modify metadata operations ================"
14761
14762 test_183() { # LU-2275
14763         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14764         remote_mds_nodsh && skip "remote MDS with nodsh"
14765         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14766                 skip "Need MDS version at least 2.3.56"
14767
14768         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14769         echo aaa > $DIR/$tdir/$tfile
14770
14771 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14772         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14773
14774         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14775         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14776
14777         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14778
14779         # Flush negative dentry cache
14780         touch $DIR/$tdir/$tfile
14781
14782         # We are not checking for any leaked references here, they'll
14783         # become evident next time we do cleanup with module unload.
14784         rm -rf $DIR/$tdir
14785 }
14786 run_test 183 "No crash or request leak in case of strange dispositions ========"
14787
14788 # test suite 184 is for LU-2016, LU-2017
14789 test_184a() {
14790         check_swap_layouts_support
14791
14792         dir0=$DIR/$tdir/$testnum
14793         test_mkdir -p -c1 $dir0
14794         ref1=/etc/passwd
14795         ref2=/etc/group
14796         file1=$dir0/f1
14797         file2=$dir0/f2
14798         $LFS setstripe -c1 $file1
14799         cp $ref1 $file1
14800         $LFS setstripe -c2 $file2
14801         cp $ref2 $file2
14802         gen1=$($LFS getstripe -g $file1)
14803         gen2=$($LFS getstripe -g $file2)
14804
14805         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14806         gen=$($LFS getstripe -g $file1)
14807         [[ $gen1 != $gen ]] ||
14808                 "Layout generation on $file1 does not change"
14809         gen=$($LFS getstripe -g $file2)
14810         [[ $gen2 != $gen ]] ||
14811                 "Layout generation on $file2 does not change"
14812
14813         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14814         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14815
14816         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14817 }
14818 run_test 184a "Basic layout swap"
14819
14820 test_184b() {
14821         check_swap_layouts_support
14822
14823         dir0=$DIR/$tdir/$testnum
14824         mkdir -p $dir0 || error "creating dir $dir0"
14825         file1=$dir0/f1
14826         file2=$dir0/f2
14827         file3=$dir0/f3
14828         dir1=$dir0/d1
14829         dir2=$dir0/d2
14830         mkdir $dir1 $dir2
14831         $LFS setstripe -c1 $file1
14832         $LFS setstripe -c2 $file2
14833         $LFS setstripe -c1 $file3
14834         chown $RUNAS_ID $file3
14835         gen1=$($LFS getstripe -g $file1)
14836         gen2=$($LFS getstripe -g $file2)
14837
14838         $LFS swap_layouts $dir1 $dir2 &&
14839                 error "swap of directories layouts should fail"
14840         $LFS swap_layouts $dir1 $file1 &&
14841                 error "swap of directory and file layouts should fail"
14842         $RUNAS $LFS swap_layouts $file1 $file2 &&
14843                 error "swap of file we cannot write should fail"
14844         $LFS swap_layouts $file1 $file3 &&
14845                 error "swap of file with different owner should fail"
14846         /bin/true # to clear error code
14847 }
14848 run_test 184b "Forbidden layout swap (will generate errors)"
14849
14850 test_184c() {
14851         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14852         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14853         check_swap_layouts_support
14854
14855         local dir0=$DIR/$tdir/$testnum
14856         mkdir -p $dir0 || error "creating dir $dir0"
14857
14858         local ref1=$dir0/ref1
14859         local ref2=$dir0/ref2
14860         local file1=$dir0/file1
14861         local file2=$dir0/file2
14862         # create a file large enough for the concurrent test
14863         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14864         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14865         echo "ref file size: ref1($(stat -c %s $ref1))," \
14866              "ref2($(stat -c %s $ref2))"
14867
14868         cp $ref2 $file2
14869         dd if=$ref1 of=$file1 bs=16k &
14870         local DD_PID=$!
14871
14872         # Make sure dd starts to copy file
14873         while [ ! -f $file1 ]; do sleep 0.1; done
14874
14875         $LFS swap_layouts $file1 $file2
14876         local rc=$?
14877         wait $DD_PID
14878         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14879         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14880
14881         # how many bytes copied before swapping layout
14882         local copied=$(stat -c %s $file2)
14883         local remaining=$(stat -c %s $ref1)
14884         remaining=$((remaining - copied))
14885         echo "Copied $copied bytes before swapping layout..."
14886
14887         cmp -n $copied $file1 $ref2 | grep differ &&
14888                 error "Content mismatch [0, $copied) of ref2 and file1"
14889         cmp -n $copied $file2 $ref1 ||
14890                 error "Content mismatch [0, $copied) of ref1 and file2"
14891         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14892                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14893
14894         # clean up
14895         rm -f $ref1 $ref2 $file1 $file2
14896 }
14897 run_test 184c "Concurrent write and layout swap"
14898
14899 test_184d() {
14900         check_swap_layouts_support
14901         [ -z "$(which getfattr 2>/dev/null)" ] &&
14902                 skip_env "no getfattr command"
14903
14904         local file1=$DIR/$tdir/$tfile-1
14905         local file2=$DIR/$tdir/$tfile-2
14906         local file3=$DIR/$tdir/$tfile-3
14907         local lovea1
14908         local lovea2
14909
14910         mkdir -p $DIR/$tdir
14911         touch $file1 || error "create $file1 failed"
14912         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14913                 error "create $file2 failed"
14914         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14915                 error "create $file3 failed"
14916         lovea1=$(get_layout_param $file1)
14917
14918         $LFS swap_layouts $file2 $file3 ||
14919                 error "swap $file2 $file3 layouts failed"
14920         $LFS swap_layouts $file1 $file2 ||
14921                 error "swap $file1 $file2 layouts failed"
14922
14923         lovea2=$(get_layout_param $file2)
14924         echo "$lovea1"
14925         echo "$lovea2"
14926         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14927
14928         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14929         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14930 }
14931 run_test 184d "allow stripeless layouts swap"
14932
14933 test_184e() {
14934         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14935                 skip "Need MDS version at least 2.6.94"
14936         check_swap_layouts_support
14937         [ -z "$(which getfattr 2>/dev/null)" ] &&
14938                 skip_env "no getfattr command"
14939
14940         local file1=$DIR/$tdir/$tfile-1
14941         local file2=$DIR/$tdir/$tfile-2
14942         local file3=$DIR/$tdir/$tfile-3
14943         local lovea
14944
14945         mkdir -p $DIR/$tdir
14946         touch $file1 || error "create $file1 failed"
14947         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14948                 error "create $file2 failed"
14949         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14950                 error "create $file3 failed"
14951
14952         $LFS swap_layouts $file1 $file2 ||
14953                 error "swap $file1 $file2 layouts failed"
14954
14955         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14956         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14957
14958         echo 123 > $file1 || error "Should be able to write into $file1"
14959
14960         $LFS swap_layouts $file1 $file3 ||
14961                 error "swap $file1 $file3 layouts failed"
14962
14963         echo 123 > $file1 || error "Should be able to write into $file1"
14964
14965         rm -rf $file1 $file2 $file3
14966 }
14967 run_test 184e "Recreate layout after stripeless layout swaps"
14968
14969 test_184f() {
14970         # Create a file with name longer than sizeof(struct stat) ==
14971         # 144 to see if we can get chars from the file name to appear
14972         # in the returned striping. Note that 'f' == 0x66.
14973         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14974
14975         mkdir -p $DIR/$tdir
14976         mcreate $DIR/$tdir/$file
14977         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14978                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14979         fi
14980 }
14981 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14982
14983 test_185() { # LU-2441
14984         # LU-3553 - no volatile file support in old servers
14985         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14986                 skip "Need MDS version at least 2.3.60"
14987
14988         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14989         touch $DIR/$tdir/spoo
14990         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14991         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14992                 error "cannot create/write a volatile file"
14993         [ "$FILESET" == "" ] &&
14994         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14995                 error "FID is still valid after close"
14996
14997         multiop_bg_pause $DIR/$tdir vVw4096_c
14998         local multi_pid=$!
14999
15000         local OLD_IFS=$IFS
15001         IFS=":"
15002         local fidv=($fid)
15003         IFS=$OLD_IFS
15004         # assume that the next FID for this client is sequential, since stdout
15005         # is unfortunately eaten by multiop_bg_pause
15006         local n=$((${fidv[1]} + 1))
15007         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
15008         if [ "$FILESET" == "" ]; then
15009                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
15010                         error "FID is missing before close"
15011         fi
15012         kill -USR1 $multi_pid
15013         # 1 second delay, so if mtime change we will see it
15014         sleep 1
15015         local mtime2=$(stat -c "%Y" $DIR/$tdir)
15016         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
15017 }
15018 run_test 185 "Volatile file support"
15019
15020 function create_check_volatile() {
15021         local idx=$1
15022         local tgt
15023
15024         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
15025         local PID=$!
15026         sleep 1
15027         local FID=$(cat /tmp/${tfile}.fid)
15028         [ "$FID" == "" ] && error "can't get FID for volatile"
15029         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
15030         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
15031         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
15032         kill -USR1 $PID
15033         wait
15034         sleep 1
15035         cancel_lru_locks mdc # flush opencache
15036         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
15037         return 0
15038 }
15039
15040 test_185a(){
15041         # LU-12516 - volatile creation via .lustre
15042         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
15043                 skip "Need MDS version at least 2.3.55"
15044
15045         create_check_volatile 0
15046         [ $MDSCOUNT -lt 2 ] && return 0
15047
15048         # DNE case
15049         create_check_volatile 1
15050
15051         return 0
15052 }
15053 run_test 185a "Volatile file creation in .lustre/fid/"
15054
15055 test_187a() {
15056         remote_mds_nodsh && skip "remote MDS with nodsh"
15057         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15058                 skip "Need MDS version at least 2.3.0"
15059
15060         local dir0=$DIR/$tdir/$testnum
15061         mkdir -p $dir0 || error "creating dir $dir0"
15062
15063         local file=$dir0/file1
15064         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
15065         local dv1=$($LFS data_version $file)
15066         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
15067         local dv2=$($LFS data_version $file)
15068         [[ $dv1 != $dv2 ]] ||
15069                 error "data version did not change on write $dv1 == $dv2"
15070
15071         # clean up
15072         rm -f $file1
15073 }
15074 run_test 187a "Test data version change"
15075
15076 test_187b() {
15077         remote_mds_nodsh && skip "remote MDS with nodsh"
15078         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
15079                 skip "Need MDS version at least 2.3.0"
15080
15081         local dir0=$DIR/$tdir/$testnum
15082         mkdir -p $dir0 || error "creating dir $dir0"
15083
15084         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
15085         [[ ${DV[0]} != ${DV[1]} ]] ||
15086                 error "data version did not change on write"\
15087                       " ${DV[0]} == ${DV[1]}"
15088
15089         # clean up
15090         rm -f $file1
15091 }
15092 run_test 187b "Test data version change on volatile file"
15093
15094 test_200() {
15095         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15096         remote_mgs_nodsh && skip "remote MGS with nodsh"
15097         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
15098
15099         local POOL=${POOL:-cea1}
15100         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
15101         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
15102         # Pool OST targets
15103         local first_ost=0
15104         local last_ost=$(($OSTCOUNT - 1))
15105         local ost_step=2
15106         local ost_list=$(seq $first_ost $ost_step $last_ost)
15107         local ost_range="$first_ost $last_ost $ost_step"
15108         local test_path=$POOL_ROOT/$POOL_DIR_NAME
15109         local file_dir=$POOL_ROOT/file_tst
15110         local subdir=$test_path/subdir
15111         local rc=0
15112
15113         while : ; do
15114                 # former test_200a test_200b
15115                 pool_add $POOL                          || { rc=$? ; break; }
15116                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
15117                 # former test_200c test_200d
15118                 mkdir -p $test_path
15119                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
15120                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
15121                 mkdir -p $subdir
15122                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
15123                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
15124                                                         || { rc=$? ; break; }
15125                 # former test_200e test_200f
15126                 local files=$((OSTCOUNT*3))
15127                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
15128                                                         || { rc=$? ; break; }
15129                 pool_create_files $POOL $file_dir $files "$ost_list" \
15130                                                         || { rc=$? ; break; }
15131                 # former test_200g test_200h
15132                 pool_lfs_df $POOL                       || { rc=$? ; break; }
15133                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
15134
15135                 # former test_201a test_201b test_201c
15136                 pool_remove_first_target $POOL          || { rc=$? ; break; }
15137
15138                 local f=$test_path/$tfile
15139                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
15140                 pool_remove $POOL $f                    || { rc=$? ; break; }
15141                 break
15142         done
15143
15144         destroy_test_pools
15145
15146         return $rc
15147 }
15148 run_test 200 "OST pools"
15149
15150 # usage: default_attr <count | size | offset>
15151 default_attr() {
15152         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
15153 }
15154
15155 # usage: check_default_stripe_attr
15156 check_default_stripe_attr() {
15157         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
15158         case $1 in
15159         --stripe-count|-c)
15160                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
15161         --stripe-size|-S)
15162                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
15163         --stripe-index|-i)
15164                 EXPECTED=-1;;
15165         *)
15166                 error "unknown getstripe attr '$1'"
15167         esac
15168
15169         [ $ACTUAL == $EXPECTED ] ||
15170                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
15171 }
15172
15173 test_204a() {
15174         test_mkdir $DIR/$tdir
15175         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
15176
15177         check_default_stripe_attr --stripe-count
15178         check_default_stripe_attr --stripe-size
15179         check_default_stripe_attr --stripe-index
15180 }
15181 run_test 204a "Print default stripe attributes"
15182
15183 test_204b() {
15184         test_mkdir $DIR/$tdir
15185         $LFS setstripe --stripe-count 1 $DIR/$tdir
15186
15187         check_default_stripe_attr --stripe-size
15188         check_default_stripe_attr --stripe-index
15189 }
15190 run_test 204b "Print default stripe size and offset"
15191
15192 test_204c() {
15193         test_mkdir $DIR/$tdir
15194         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15195
15196         check_default_stripe_attr --stripe-count
15197         check_default_stripe_attr --stripe-index
15198 }
15199 run_test 204c "Print default stripe count and offset"
15200
15201 test_204d() {
15202         test_mkdir $DIR/$tdir
15203         $LFS setstripe --stripe-index 0 $DIR/$tdir
15204
15205         check_default_stripe_attr --stripe-count
15206         check_default_stripe_attr --stripe-size
15207 }
15208 run_test 204d "Print default stripe count and size"
15209
15210 test_204e() {
15211         test_mkdir $DIR/$tdir
15212         $LFS setstripe -d $DIR/$tdir
15213
15214         check_default_stripe_attr --stripe-count --raw
15215         check_default_stripe_attr --stripe-size --raw
15216         check_default_stripe_attr --stripe-index --raw
15217 }
15218 run_test 204e "Print raw stripe attributes"
15219
15220 test_204f() {
15221         test_mkdir $DIR/$tdir
15222         $LFS setstripe --stripe-count 1 $DIR/$tdir
15223
15224         check_default_stripe_attr --stripe-size --raw
15225         check_default_stripe_attr --stripe-index --raw
15226 }
15227 run_test 204f "Print raw stripe size and offset"
15228
15229 test_204g() {
15230         test_mkdir $DIR/$tdir
15231         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15232
15233         check_default_stripe_attr --stripe-count --raw
15234         check_default_stripe_attr --stripe-index --raw
15235 }
15236 run_test 204g "Print raw stripe count and offset"
15237
15238 test_204h() {
15239         test_mkdir $DIR/$tdir
15240         $LFS setstripe --stripe-index 0 $DIR/$tdir
15241
15242         check_default_stripe_attr --stripe-count --raw
15243         check_default_stripe_attr --stripe-size --raw
15244 }
15245 run_test 204h "Print raw stripe count and size"
15246
15247 # Figure out which job scheduler is being used, if any,
15248 # or use a fake one
15249 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15250         JOBENV=SLURM_JOB_ID
15251 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15252         JOBENV=LSB_JOBID
15253 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15254         JOBENV=PBS_JOBID
15255 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15256         JOBENV=LOADL_STEP_ID
15257 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15258         JOBENV=JOB_ID
15259 else
15260         $LCTL list_param jobid_name > /dev/null 2>&1
15261         if [ $? -eq 0 ]; then
15262                 JOBENV=nodelocal
15263         else
15264                 JOBENV=FAKE_JOBID
15265         fi
15266 fi
15267 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15268
15269 verify_jobstats() {
15270         local cmd=($1)
15271         shift
15272         local facets="$@"
15273
15274 # we don't really need to clear the stats for this test to work, since each
15275 # command has a unique jobid, but it makes debugging easier if needed.
15276 #       for facet in $facets; do
15277 #               local dev=$(convert_facet2label $facet)
15278 #               # clear old jobstats
15279 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15280 #       done
15281
15282         # use a new JobID for each test, or we might see an old one
15283         [ "$JOBENV" = "FAKE_JOBID" ] &&
15284                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15285
15286         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15287
15288         [ "$JOBENV" = "nodelocal" ] && {
15289                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15290                 $LCTL set_param jobid_name=$FAKE_JOBID
15291                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15292         }
15293
15294         log "Test: ${cmd[*]}"
15295         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15296
15297         if [ $JOBENV = "FAKE_JOBID" ]; then
15298                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15299         else
15300                 ${cmd[*]}
15301         fi
15302
15303         # all files are created on OST0000
15304         for facet in $facets; do
15305                 local stats="*.$(convert_facet2label $facet).job_stats"
15306
15307                 # strip out libtool wrappers for in-tree executables
15308                 if [ $(do_facet $facet lctl get_param $stats |
15309                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15310                         do_facet $facet lctl get_param $stats
15311                         error "No jobstats for $JOBVAL found on $facet::$stats"
15312                 fi
15313         done
15314 }
15315
15316 jobstats_set() {
15317         local new_jobenv=$1
15318
15319         set_persistent_param_and_check client "jobid_var" \
15320                 "$FSNAME.sys.jobid_var" $new_jobenv
15321 }
15322
15323 test_205() { # Job stats
15324         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15325         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15326                 skip "Need MDS version with at least 2.7.1"
15327         remote_mgs_nodsh && skip "remote MGS with nodsh"
15328         remote_mds_nodsh && skip "remote MDS with nodsh"
15329         remote_ost_nodsh && skip "remote OST with nodsh"
15330         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15331                 skip "Server doesn't support jobstats"
15332         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15333
15334         local old_jobenv=$($LCTL get_param -n jobid_var)
15335         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15336
15337         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15338                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15339         else
15340                 stack_trap "do_facet mgs $PERM_CMD \
15341                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15342         fi
15343         changelog_register
15344
15345         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15346                                 mdt.*.job_cleanup_interval | head -n 1)
15347         local new_interval=5
15348         do_facet $SINGLEMDS \
15349                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15350         stack_trap "do_facet $SINGLEMDS \
15351                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15352         local start=$SECONDS
15353
15354         local cmd
15355         # mkdir
15356         cmd="mkdir $DIR/$tdir"
15357         verify_jobstats "$cmd" "$SINGLEMDS"
15358         # rmdir
15359         cmd="rmdir $DIR/$tdir"
15360         verify_jobstats "$cmd" "$SINGLEMDS"
15361         # mkdir on secondary MDT
15362         if [ $MDSCOUNT -gt 1 ]; then
15363                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15364                 verify_jobstats "$cmd" "mds2"
15365         fi
15366         # mknod
15367         cmd="mknod $DIR/$tfile c 1 3"
15368         verify_jobstats "$cmd" "$SINGLEMDS"
15369         # unlink
15370         cmd="rm -f $DIR/$tfile"
15371         verify_jobstats "$cmd" "$SINGLEMDS"
15372         # create all files on OST0000 so verify_jobstats can find OST stats
15373         # open & close
15374         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15375         verify_jobstats "$cmd" "$SINGLEMDS"
15376         # setattr
15377         cmd="touch $DIR/$tfile"
15378         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15379         # write
15380         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15381         verify_jobstats "$cmd" "ost1"
15382         # read
15383         cancel_lru_locks osc
15384         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15385         verify_jobstats "$cmd" "ost1"
15386         # truncate
15387         cmd="$TRUNCATE $DIR/$tfile 0"
15388         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15389         # rename
15390         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15391         verify_jobstats "$cmd" "$SINGLEMDS"
15392         # jobstats expiry - sleep until old stats should be expired
15393         local left=$((new_interval + 5 - (SECONDS - start)))
15394         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15395                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15396                         "0" $left
15397         cmd="mkdir $DIR/$tdir.expire"
15398         verify_jobstats "$cmd" "$SINGLEMDS"
15399         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15400             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15401
15402         # Ensure that jobid are present in changelog (if supported by MDS)
15403         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15404                 changelog_dump | tail -10
15405                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15406                 [ $jobids -eq 9 ] ||
15407                         error "Wrong changelog jobid count $jobids != 9"
15408
15409                 # LU-5862
15410                 JOBENV="disable"
15411                 jobstats_set $JOBENV
15412                 touch $DIR/$tfile
15413                 changelog_dump | grep $tfile
15414                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15415                 [ $jobids -eq 0 ] ||
15416                         error "Unexpected jobids when jobid_var=$JOBENV"
15417         fi
15418
15419         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15420         JOBENV="JOBCOMPLEX"
15421         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15422
15423         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15424 }
15425 run_test 205 "Verify job stats"
15426
15427 # LU-1480, LU-1773 and LU-1657
15428 test_206() {
15429         mkdir -p $DIR/$tdir
15430         $LFS setstripe -c -1 $DIR/$tdir
15431 #define OBD_FAIL_LOV_INIT 0x1403
15432         $LCTL set_param fail_loc=0xa0001403
15433         $LCTL set_param fail_val=1
15434         touch $DIR/$tdir/$tfile || true
15435 }
15436 run_test 206 "fail lov_init_raid0() doesn't lbug"
15437
15438 test_207a() {
15439         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15440         local fsz=`stat -c %s $DIR/$tfile`
15441         cancel_lru_locks mdc
15442
15443         # do not return layout in getattr intent
15444 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15445         $LCTL set_param fail_loc=0x170
15446         local sz=`stat -c %s $DIR/$tfile`
15447
15448         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15449
15450         rm -rf $DIR/$tfile
15451 }
15452 run_test 207a "can refresh layout at glimpse"
15453
15454 test_207b() {
15455         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15456         local cksum=`md5sum $DIR/$tfile`
15457         local fsz=`stat -c %s $DIR/$tfile`
15458         cancel_lru_locks mdc
15459         cancel_lru_locks osc
15460
15461         # do not return layout in getattr intent
15462 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15463         $LCTL set_param fail_loc=0x171
15464
15465         # it will refresh layout after the file is opened but before read issues
15466         echo checksum is "$cksum"
15467         echo "$cksum" |md5sum -c --quiet || error "file differs"
15468
15469         rm -rf $DIR/$tfile
15470 }
15471 run_test 207b "can refresh layout at open"
15472
15473 test_208() {
15474         # FIXME: in this test suite, only RD lease is used. This is okay
15475         # for now as only exclusive open is supported. After generic lease
15476         # is done, this test suite should be revised. - Jinshan
15477
15478         remote_mds_nodsh && skip "remote MDS with nodsh"
15479         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15480                 skip "Need MDS version at least 2.4.52"
15481
15482         echo "==== test 1: verify get lease work"
15483         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15484
15485         echo "==== test 2: verify lease can be broken by upcoming open"
15486         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15487         local PID=$!
15488         sleep 1
15489
15490         $MULTIOP $DIR/$tfile oO_RDONLY:c
15491         kill -USR1 $PID && wait $PID || error "break lease error"
15492
15493         echo "==== test 3: verify lease can't be granted if an open already exists"
15494         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15495         local PID=$!
15496         sleep 1
15497
15498         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15499         kill -USR1 $PID && wait $PID || error "open file error"
15500
15501         echo "==== test 4: lease can sustain over recovery"
15502         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15503         PID=$!
15504         sleep 1
15505
15506         fail mds1
15507
15508         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15509
15510         echo "==== test 5: lease broken can't be regained by replay"
15511         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15512         PID=$!
15513         sleep 1
15514
15515         # open file to break lease and then recovery
15516         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15517         fail mds1
15518
15519         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15520
15521         rm -f $DIR/$tfile
15522 }
15523 run_test 208 "Exclusive open"
15524
15525 test_209() {
15526         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15527                 skip_env "must have disp_stripe"
15528
15529         touch $DIR/$tfile
15530         sync; sleep 5; sync;
15531
15532         echo 3 > /proc/sys/vm/drop_caches
15533         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15534
15535         # open/close 500 times
15536         for i in $(seq 500); do
15537                 cat $DIR/$tfile
15538         done
15539
15540         echo 3 > /proc/sys/vm/drop_caches
15541         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15542
15543         echo "before: $req_before, after: $req_after"
15544         [ $((req_after - req_before)) -ge 300 ] &&
15545                 error "open/close requests are not freed"
15546         return 0
15547 }
15548 run_test 209 "read-only open/close requests should be freed promptly"
15549
15550 test_212() {
15551         size=`date +%s`
15552         size=$((size % 8192 + 1))
15553         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15554         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15555         rm -f $DIR/f212 $DIR/f212.xyz
15556 }
15557 run_test 212 "Sendfile test ============================================"
15558
15559 test_213() {
15560         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15561         cancel_lru_locks osc
15562         lctl set_param fail_loc=0x8000040f
15563         # generate a read lock
15564         cat $DIR/$tfile > /dev/null
15565         # write to the file, it will try to cancel the above read lock.
15566         cat /etc/hosts >> $DIR/$tfile
15567 }
15568 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15569
15570 test_214() { # for bug 20133
15571         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15572         for (( i=0; i < 340; i++ )) ; do
15573                 touch $DIR/$tdir/d214c/a$i
15574         done
15575
15576         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15577         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15578         ls $DIR/d214c || error "ls $DIR/d214c failed"
15579         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15580         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15581 }
15582 run_test 214 "hash-indexed directory test - bug 20133"
15583
15584 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15585 create_lnet_proc_files() {
15586         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15587 }
15588
15589 # counterpart of create_lnet_proc_files
15590 remove_lnet_proc_files() {
15591         rm -f $TMP/lnet_$1.sys
15592 }
15593
15594 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15595 # 3rd arg as regexp for body
15596 check_lnet_proc_stats() {
15597         local l=$(cat "$TMP/lnet_$1" |wc -l)
15598         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15599
15600         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15601 }
15602
15603 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15604 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15605 # optional and can be regexp for 2nd line (lnet.routes case)
15606 check_lnet_proc_entry() {
15607         local blp=2          # blp stands for 'position of 1st line of body'
15608         [ -z "$5" ] || blp=3 # lnet.routes case
15609
15610         local l=$(cat "$TMP/lnet_$1" |wc -l)
15611         # subtracting one from $blp because the body can be empty
15612         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15613
15614         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15615                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15616
15617         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15618                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15619
15620         # bail out if any unexpected line happened
15621         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15622         [ "$?" != 0 ] || error "$2 misformatted"
15623 }
15624
15625 test_215() { # for bugs 18102, 21079, 21517
15626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15627
15628         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15629         local P='[1-9][0-9]*'           # positive numeric
15630         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15631         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15632         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15633         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15634
15635         local L1 # regexp for 1st line
15636         local L2 # regexp for 2nd line (optional)
15637         local BR # regexp for the rest (body)
15638
15639         # lnet.stats should look as 11 space-separated non-negative numerics
15640         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15641         create_lnet_proc_files "stats"
15642         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15643         remove_lnet_proc_files "stats"
15644
15645         # lnet.routes should look like this:
15646         # Routing disabled/enabled
15647         # net hops priority state router
15648         # where net is a string like tcp0, hops > 0, priority >= 0,
15649         # state is up/down,
15650         # router is a string like 192.168.1.1@tcp2
15651         L1="^Routing (disabled|enabled)$"
15652         L2="^net +hops +priority +state +router$"
15653         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15654         create_lnet_proc_files "routes"
15655         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15656         remove_lnet_proc_files "routes"
15657
15658         # lnet.routers should look like this:
15659         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15660         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15661         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15662         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15663         L1="^ref +rtr_ref +alive +router$"
15664         BR="^$P +$P +(up|down) +$NID$"
15665         create_lnet_proc_files "routers"
15666         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15667         remove_lnet_proc_files "routers"
15668
15669         # lnet.peers should look like this:
15670         # nid refs state last max rtr min tx min queue
15671         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15672         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15673         # numeric (0 or >0 or <0), queue >= 0.
15674         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15675         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15676         create_lnet_proc_files "peers"
15677         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15678         remove_lnet_proc_files "peers"
15679
15680         # lnet.buffers  should look like this:
15681         # pages count credits min
15682         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15683         L1="^pages +count +credits +min$"
15684         BR="^ +$N +$N +$I +$I$"
15685         create_lnet_proc_files "buffers"
15686         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15687         remove_lnet_proc_files "buffers"
15688
15689         # lnet.nis should look like this:
15690         # nid status alive refs peer rtr max tx min
15691         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15692         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15693         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15694         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15695         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15696         create_lnet_proc_files "nis"
15697         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15698         remove_lnet_proc_files "nis"
15699
15700         # can we successfully write to lnet.stats?
15701         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15702 }
15703 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15704
15705 test_216() { # bug 20317
15706         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15707         remote_ost_nodsh && skip "remote OST with nodsh"
15708
15709         local node
15710         local facets=$(get_facets OST)
15711         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15712
15713         save_lustre_params client "osc.*.contention_seconds" > $p
15714         save_lustre_params $facets \
15715                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15716         save_lustre_params $facets \
15717                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15718         save_lustre_params $facets \
15719                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15720         clear_stats osc.*.osc_stats
15721
15722         # agressive lockless i/o settings
15723         do_nodes $(comma_list $(osts_nodes)) \
15724                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15725                         ldlm.namespaces.filter-*.contended_locks=0 \
15726                         ldlm.namespaces.filter-*.contention_seconds=60"
15727         lctl set_param -n osc.*.contention_seconds=60
15728
15729         $DIRECTIO write $DIR/$tfile 0 10 4096
15730         $CHECKSTAT -s 40960 $DIR/$tfile
15731
15732         # disable lockless i/o
15733         do_nodes $(comma_list $(osts_nodes)) \
15734                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15735                         ldlm.namespaces.filter-*.contended_locks=32 \
15736                         ldlm.namespaces.filter-*.contention_seconds=0"
15737         lctl set_param -n osc.*.contention_seconds=0
15738         clear_stats osc.*.osc_stats
15739
15740         dd if=/dev/zero of=$DIR/$tfile count=0
15741         $CHECKSTAT -s 0 $DIR/$tfile
15742
15743         restore_lustre_params <$p
15744         rm -f $p
15745         rm $DIR/$tfile
15746 }
15747 run_test 216 "check lockless direct write updates file size and kms correctly"
15748
15749 test_217() { # bug 22430
15750         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15751
15752         local node
15753         local nid
15754
15755         for node in $(nodes_list); do
15756                 nid=$(host_nids_address $node $NETTYPE)
15757                 if [[ $nid = *-* ]] ; then
15758                         echo "lctl ping $(h2nettype $nid)"
15759                         lctl ping $(h2nettype $nid)
15760                 else
15761                         echo "skipping $node (no hyphen detected)"
15762                 fi
15763         done
15764 }
15765 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15766
15767 test_218() {
15768        # do directio so as not to populate the page cache
15769        log "creating a 10 Mb file"
15770        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15771        log "starting reads"
15772        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15773        log "truncating the file"
15774        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15775        log "killing dd"
15776        kill %+ || true # reads might have finished
15777        echo "wait until dd is finished"
15778        wait
15779        log "removing the temporary file"
15780        rm -rf $DIR/$tfile || error "tmp file removal failed"
15781 }
15782 run_test 218 "parallel read and truncate should not deadlock"
15783
15784 test_219() {
15785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15786
15787         # write one partial page
15788         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15789         # set no grant so vvp_io_commit_write will do sync write
15790         $LCTL set_param fail_loc=0x411
15791         # write a full page at the end of file
15792         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15793
15794         $LCTL set_param fail_loc=0
15795         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15796         $LCTL set_param fail_loc=0x411
15797         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15798
15799         # LU-4201
15800         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15801         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15802 }
15803 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15804
15805 test_220() { #LU-325
15806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15807         remote_ost_nodsh && skip "remote OST with nodsh"
15808         remote_mds_nodsh && skip "remote MDS with nodsh"
15809         remote_mgs_nodsh && skip "remote MGS with nodsh"
15810
15811         local OSTIDX=0
15812
15813         # create on MDT0000 so the last_id and next_id are correct
15814         mkdir $DIR/$tdir
15815         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15816         OST=${OST%_UUID}
15817
15818         # on the mdt's osc
15819         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15820         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15821                         osp.$mdtosc_proc1.prealloc_last_id)
15822         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15823                         osp.$mdtosc_proc1.prealloc_next_id)
15824
15825         $LFS df -i
15826
15827         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15828         #define OBD_FAIL_OST_ENOINO              0x229
15829         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15830         create_pool $FSNAME.$TESTNAME || return 1
15831         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15832
15833         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15834
15835         MDSOBJS=$((last_id - next_id))
15836         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15837
15838         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15839         echo "OST still has $count kbytes free"
15840
15841         echo "create $MDSOBJS files @next_id..."
15842         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15843
15844         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15845                         osp.$mdtosc_proc1.prealloc_last_id)
15846         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15847                         osp.$mdtosc_proc1.prealloc_next_id)
15848
15849         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15850         $LFS df -i
15851
15852         echo "cleanup..."
15853
15854         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15855         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15856
15857         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15858                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15859         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15860                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15861         echo "unlink $MDSOBJS files @$next_id..."
15862         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15863 }
15864 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15865
15866 test_221() {
15867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15868
15869         dd if=`which date` of=$MOUNT/date oflag=sync
15870         chmod +x $MOUNT/date
15871
15872         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15873         $LCTL set_param fail_loc=0x80001401
15874
15875         $MOUNT/date > /dev/null
15876         rm -f $MOUNT/date
15877 }
15878 run_test 221 "make sure fault and truncate race to not cause OOM"
15879
15880 test_222a () {
15881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15882
15883         rm -rf $DIR/$tdir
15884         test_mkdir $DIR/$tdir
15885         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15886         createmany -o $DIR/$tdir/$tfile 10
15887         cancel_lru_locks mdc
15888         cancel_lru_locks osc
15889         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15890         $LCTL set_param fail_loc=0x31a
15891         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15892         $LCTL set_param fail_loc=0
15893         rm -r $DIR/$tdir
15894 }
15895 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15896
15897 test_222b () {
15898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15899
15900         rm -rf $DIR/$tdir
15901         test_mkdir $DIR/$tdir
15902         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15903         createmany -o $DIR/$tdir/$tfile 10
15904         cancel_lru_locks mdc
15905         cancel_lru_locks osc
15906         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15907         $LCTL set_param fail_loc=0x31a
15908         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15909         $LCTL set_param fail_loc=0
15910 }
15911 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15912
15913 test_223 () {
15914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15915
15916         rm -rf $DIR/$tdir
15917         test_mkdir $DIR/$tdir
15918         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15919         createmany -o $DIR/$tdir/$tfile 10
15920         cancel_lru_locks mdc
15921         cancel_lru_locks osc
15922         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15923         $LCTL set_param fail_loc=0x31b
15924         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15925         $LCTL set_param fail_loc=0
15926         rm -r $DIR/$tdir
15927 }
15928 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15929
15930 test_224a() { # LU-1039, MRP-303
15931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15932
15933         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15934         $LCTL set_param fail_loc=0x508
15935         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15936         $LCTL set_param fail_loc=0
15937         df $DIR
15938 }
15939 run_test 224a "Don't panic on bulk IO failure"
15940
15941 test_224b() { # LU-1039, MRP-303
15942         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15943
15944         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15945         cancel_lru_locks osc
15946         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15947         $LCTL set_param fail_loc=0x515
15948         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15949         $LCTL set_param fail_loc=0
15950         df $DIR
15951 }
15952 run_test 224b "Don't panic on bulk IO failure"
15953
15954 test_224c() { # LU-6441
15955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15956         remote_mds_nodsh && skip "remote MDS with nodsh"
15957
15958         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15959         save_writethrough $p
15960         set_cache writethrough on
15961
15962         local pages_per_rpc=$($LCTL get_param \
15963                                 osc.*.max_pages_per_rpc)
15964         local at_max=$($LCTL get_param -n at_max)
15965         local timeout=$($LCTL get_param -n timeout)
15966         local test_at="at_max"
15967         local param_at="$FSNAME.sys.at_max"
15968         local test_timeout="timeout"
15969         local param_timeout="$FSNAME.sys.timeout"
15970
15971         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15972
15973         set_persistent_param_and_check client "$test_at" "$param_at" 0
15974         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15975
15976         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15977         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15978         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15979         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15980         sync
15981         do_facet ost1 "$LCTL set_param fail_loc=0"
15982
15983         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15984         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15985                 $timeout
15986
15987         $LCTL set_param -n $pages_per_rpc
15988         restore_lustre_params < $p
15989         rm -f $p
15990 }
15991 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15992
15993 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15994 test_225a () {
15995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15996         if [ -z ${MDSSURVEY} ]; then
15997                 skip_env "mds-survey not found"
15998         fi
15999         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16000                 skip "Need MDS version at least 2.2.51"
16001
16002         local mds=$(facet_host $SINGLEMDS)
16003         local target=$(do_nodes $mds 'lctl dl' |
16004                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16005
16006         local cmd1="file_count=1000 thrhi=4"
16007         local cmd2="dir_count=2 layer=mdd stripe_count=0"
16008         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16009         local cmd="$cmd1 $cmd2 $cmd3"
16010
16011         rm -f ${TMP}/mds_survey*
16012         echo + $cmd
16013         eval $cmd || error "mds-survey with zero-stripe failed"
16014         cat ${TMP}/mds_survey*
16015         rm -f ${TMP}/mds_survey*
16016 }
16017 run_test 225a "Metadata survey sanity with zero-stripe"
16018
16019 test_225b () {
16020         if [ -z ${MDSSURVEY} ]; then
16021                 skip_env "mds-survey not found"
16022         fi
16023         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
16024                 skip "Need MDS version at least 2.2.51"
16025         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16026         remote_mds_nodsh && skip "remote MDS with nodsh"
16027         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
16028                 skip_env "Need to mount OST to test"
16029         fi
16030
16031         local mds=$(facet_host $SINGLEMDS)
16032         local target=$(do_nodes $mds 'lctl dl' |
16033                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
16034
16035         local cmd1="file_count=1000 thrhi=4"
16036         local cmd2="dir_count=2 layer=mdd stripe_count=1"
16037         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
16038         local cmd="$cmd1 $cmd2 $cmd3"
16039
16040         rm -f ${TMP}/mds_survey*
16041         echo + $cmd
16042         eval $cmd || error "mds-survey with stripe_count failed"
16043         cat ${TMP}/mds_survey*
16044         rm -f ${TMP}/mds_survey*
16045 }
16046 run_test 225b "Metadata survey sanity with stripe_count = 1"
16047
16048 mcreate_path2fid () {
16049         local mode=$1
16050         local major=$2
16051         local minor=$3
16052         local name=$4
16053         local desc=$5
16054         local path=$DIR/$tdir/$name
16055         local fid
16056         local rc
16057         local fid_path
16058
16059         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
16060                 error "cannot create $desc"
16061
16062         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
16063         rc=$?
16064         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
16065
16066         fid_path=$($LFS fid2path $MOUNT $fid)
16067         rc=$?
16068         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
16069
16070         [ "$path" == "$fid_path" ] ||
16071                 error "fid2path returned $fid_path, expected $path"
16072
16073         echo "pass with $path and $fid"
16074 }
16075
16076 test_226a () {
16077         rm -rf $DIR/$tdir
16078         mkdir -p $DIR/$tdir
16079
16080         mcreate_path2fid 0010666 0 0 fifo "FIFO"
16081         mcreate_path2fid 0020666 1 3 null "character special file (null)"
16082         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
16083         mcreate_path2fid 0040666 0 0 dir "directory"
16084         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
16085         mcreate_path2fid 0100666 0 0 file "regular file"
16086         mcreate_path2fid 0120666 0 0 link "symbolic link"
16087         mcreate_path2fid 0140666 0 0 sock "socket"
16088 }
16089 run_test 226a "call path2fid and fid2path on files of all type"
16090
16091 test_226b () {
16092         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16093
16094         local MDTIDX=1
16095
16096         rm -rf $DIR/$tdir
16097         mkdir -p $DIR/$tdir
16098         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
16099                 error "create remote directory failed"
16100         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
16101         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
16102                                 "character special file (null)"
16103         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
16104                                 "character special file (no device)"
16105         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
16106         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
16107                                 "block special file (loop)"
16108         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
16109         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
16110         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
16111 }
16112 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
16113
16114 # LU-1299 Executing or running ldd on a truncated executable does not
16115 # cause an out-of-memory condition.
16116 test_227() {
16117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16118         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
16119
16120         dd if=$(which date) of=$MOUNT/date bs=1k count=1
16121         chmod +x $MOUNT/date
16122
16123         $MOUNT/date > /dev/null
16124         ldd $MOUNT/date > /dev/null
16125         rm -f $MOUNT/date
16126 }
16127 run_test 227 "running truncated executable does not cause OOM"
16128
16129 # LU-1512 try to reuse idle OI blocks
16130 test_228a() {
16131         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16132         remote_mds_nodsh && skip "remote MDS with nodsh"
16133         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16134
16135         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16136         local myDIR=$DIR/$tdir
16137
16138         mkdir -p $myDIR
16139         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16140         $LCTL set_param fail_loc=0x80001002
16141         createmany -o $myDIR/t- 10000
16142         $LCTL set_param fail_loc=0
16143         # The guard is current the largest FID holder
16144         touch $myDIR/guard
16145         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16146                     tr -d '[')
16147         local IDX=$(($SEQ % 64))
16148
16149         do_facet $SINGLEMDS sync
16150         # Make sure journal flushed.
16151         sleep 6
16152         local blk1=$(do_facet $SINGLEMDS \
16153                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16154                      grep Blockcount | awk '{print $4}')
16155
16156         # Remove old files, some OI blocks will become idle.
16157         unlinkmany $myDIR/t- 10000
16158         # Create new files, idle OI blocks should be reused.
16159         createmany -o $myDIR/t- 2000
16160         do_facet $SINGLEMDS sync
16161         # Make sure journal flushed.
16162         sleep 6
16163         local blk2=$(do_facet $SINGLEMDS \
16164                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16165                      grep Blockcount | awk '{print $4}')
16166
16167         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16168 }
16169 run_test 228a "try to reuse idle OI blocks"
16170
16171 test_228b() {
16172         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16173         remote_mds_nodsh && skip "remote MDS with nodsh"
16174         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16175
16176         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16177         local myDIR=$DIR/$tdir
16178
16179         mkdir -p $myDIR
16180         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16181         $LCTL set_param fail_loc=0x80001002
16182         createmany -o $myDIR/t- 10000
16183         $LCTL set_param fail_loc=0
16184         # The guard is current the largest FID holder
16185         touch $myDIR/guard
16186         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16187                     tr -d '[')
16188         local IDX=$(($SEQ % 64))
16189
16190         do_facet $SINGLEMDS sync
16191         # Make sure journal flushed.
16192         sleep 6
16193         local blk1=$(do_facet $SINGLEMDS \
16194                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16195                      grep Blockcount | awk '{print $4}')
16196
16197         # Remove old files, some OI blocks will become idle.
16198         unlinkmany $myDIR/t- 10000
16199
16200         # stop the MDT
16201         stop $SINGLEMDS || error "Fail to stop MDT."
16202         # remount the MDT
16203         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16204
16205         df $MOUNT || error "Fail to df."
16206         # Create new files, idle OI blocks should be reused.
16207         createmany -o $myDIR/t- 2000
16208         do_facet $SINGLEMDS sync
16209         # Make sure journal flushed.
16210         sleep 6
16211         local blk2=$(do_facet $SINGLEMDS \
16212                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16213                      grep Blockcount | awk '{print $4}')
16214
16215         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16216 }
16217 run_test 228b "idle OI blocks can be reused after MDT restart"
16218
16219 #LU-1881
16220 test_228c() {
16221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16222         remote_mds_nodsh && skip "remote MDS with nodsh"
16223         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16224
16225         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16226         local myDIR=$DIR/$tdir
16227
16228         mkdir -p $myDIR
16229         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16230         $LCTL set_param fail_loc=0x80001002
16231         # 20000 files can guarantee there are index nodes in the OI file
16232         createmany -o $myDIR/t- 20000
16233         $LCTL set_param fail_loc=0
16234         # The guard is current the largest FID holder
16235         touch $myDIR/guard
16236         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16237                     tr -d '[')
16238         local IDX=$(($SEQ % 64))
16239
16240         do_facet $SINGLEMDS sync
16241         # Make sure journal flushed.
16242         sleep 6
16243         local blk1=$(do_facet $SINGLEMDS \
16244                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16245                      grep Blockcount | awk '{print $4}')
16246
16247         # Remove old files, some OI blocks will become idle.
16248         unlinkmany $myDIR/t- 20000
16249         rm -f $myDIR/guard
16250         # The OI file should become empty now
16251
16252         # Create new files, idle OI blocks should be reused.
16253         createmany -o $myDIR/t- 2000
16254         do_facet $SINGLEMDS sync
16255         # Make sure journal flushed.
16256         sleep 6
16257         local blk2=$(do_facet $SINGLEMDS \
16258                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16259                      grep Blockcount | awk '{print $4}')
16260
16261         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16262 }
16263 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16264
16265 test_229() { # LU-2482, LU-3448
16266         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16267         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16268         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16269                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16270
16271         rm -f $DIR/$tfile
16272
16273         # Create a file with a released layout and stripe count 2.
16274         $MULTIOP $DIR/$tfile H2c ||
16275                 error "failed to create file with released layout"
16276
16277         $LFS getstripe -v $DIR/$tfile
16278
16279         local pattern=$($LFS getstripe -L $DIR/$tfile)
16280         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16281
16282         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16283                 error "getstripe"
16284         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16285         stat $DIR/$tfile || error "failed to stat released file"
16286
16287         chown $RUNAS_ID $DIR/$tfile ||
16288                 error "chown $RUNAS_ID $DIR/$tfile failed"
16289
16290         chgrp $RUNAS_ID $DIR/$tfile ||
16291                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16292
16293         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16294         rm $DIR/$tfile || error "failed to remove released file"
16295 }
16296 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16297
16298 test_230a() {
16299         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16300         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16301         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16302                 skip "Need MDS version at least 2.11.52"
16303
16304         local MDTIDX=1
16305
16306         test_mkdir $DIR/$tdir
16307         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16308         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16309         [ $mdt_idx -ne 0 ] &&
16310                 error "create local directory on wrong MDT $mdt_idx"
16311
16312         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16313                         error "create remote directory failed"
16314         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16315         [ $mdt_idx -ne $MDTIDX ] &&
16316                 error "create remote directory on wrong MDT $mdt_idx"
16317
16318         createmany -o $DIR/$tdir/test_230/t- 10 ||
16319                 error "create files on remote directory failed"
16320         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16321         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16322         rm -r $DIR/$tdir || error "unlink remote directory failed"
16323 }
16324 run_test 230a "Create remote directory and files under the remote directory"
16325
16326 test_230b() {
16327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16328         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16329         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16330                 skip "Need MDS version at least 2.11.52"
16331
16332         local MDTIDX=1
16333         local mdt_index
16334         local i
16335         local file
16336         local pid
16337         local stripe_count
16338         local migrate_dir=$DIR/$tdir/migrate_dir
16339         local other_dir=$DIR/$tdir/other_dir
16340
16341         test_mkdir $DIR/$tdir
16342         test_mkdir -i0 -c1 $migrate_dir
16343         test_mkdir -i0 -c1 $other_dir
16344         for ((i=0; i<10; i++)); do
16345                 mkdir -p $migrate_dir/dir_${i}
16346                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16347                         error "create files under remote dir failed $i"
16348         done
16349
16350         cp /etc/passwd $migrate_dir/$tfile
16351         cp /etc/passwd $other_dir/$tfile
16352         chattr +SAD $migrate_dir
16353         chattr +SAD $migrate_dir/$tfile
16354
16355         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16356         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16357         local old_dir_mode=$(stat -c%f $migrate_dir)
16358         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16359
16360         mkdir -p $migrate_dir/dir_default_stripe2
16361         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16362         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16363
16364         mkdir -p $other_dir
16365         ln $migrate_dir/$tfile $other_dir/luna
16366         ln $migrate_dir/$tfile $migrate_dir/sofia
16367         ln $other_dir/$tfile $migrate_dir/david
16368         ln -s $migrate_dir/$tfile $other_dir/zachary
16369         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16370         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16371
16372         $LFS migrate -m $MDTIDX $migrate_dir ||
16373                 error "fails on migrating remote dir to MDT1"
16374
16375         echo "migratate to MDT1, then checking.."
16376         for ((i = 0; i < 10; i++)); do
16377                 for file in $(find $migrate_dir/dir_${i}); do
16378                         mdt_index=$($LFS getstripe -m $file)
16379                         [ $mdt_index == $MDTIDX ] ||
16380                                 error "$file is not on MDT${MDTIDX}"
16381                 done
16382         done
16383
16384         # the multiple link file should still in MDT0
16385         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16386         [ $mdt_index == 0 ] ||
16387                 error "$file is not on MDT${MDTIDX}"
16388
16389         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16390         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16391                 error " expect $old_dir_flag get $new_dir_flag"
16392
16393         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16394         [ "$old_file_flag" = "$new_file_flag" ] ||
16395                 error " expect $old_file_flag get $new_file_flag"
16396
16397         local new_dir_mode=$(stat -c%f $migrate_dir)
16398         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16399                 error "expect mode $old_dir_mode get $new_dir_mode"
16400
16401         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16402         [ "$old_file_mode" = "$new_file_mode" ] ||
16403                 error "expect mode $old_file_mode get $new_file_mode"
16404
16405         diff /etc/passwd $migrate_dir/$tfile ||
16406                 error "$tfile different after migration"
16407
16408         diff /etc/passwd $other_dir/luna ||
16409                 error "luna different after migration"
16410
16411         diff /etc/passwd $migrate_dir/sofia ||
16412                 error "sofia different after migration"
16413
16414         diff /etc/passwd $migrate_dir/david ||
16415                 error "david different after migration"
16416
16417         diff /etc/passwd $other_dir/zachary ||
16418                 error "zachary different after migration"
16419
16420         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16421                 error "${tfile}_ln different after migration"
16422
16423         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16424                 error "${tfile}_ln_other different after migration"
16425
16426         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16427         [ $stripe_count = 2 ] ||
16428                 error "dir strpe_count $d != 2 after migration."
16429
16430         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16431         [ $stripe_count = 2 ] ||
16432                 error "file strpe_count $d != 2 after migration."
16433
16434         #migrate back to MDT0
16435         MDTIDX=0
16436
16437         $LFS migrate -m $MDTIDX $migrate_dir ||
16438                 error "fails on migrating remote dir to MDT0"
16439
16440         echo "migrate back to MDT0, checking.."
16441         for file in $(find $migrate_dir); do
16442                 mdt_index=$($LFS getstripe -m $file)
16443                 [ $mdt_index == $MDTIDX ] ||
16444                         error "$file is not on MDT${MDTIDX}"
16445         done
16446
16447         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16448         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16449                 error " expect $old_dir_flag get $new_dir_flag"
16450
16451         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16452         [ "$old_file_flag" = "$new_file_flag" ] ||
16453                 error " expect $old_file_flag get $new_file_flag"
16454
16455         local new_dir_mode=$(stat -c%f $migrate_dir)
16456         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16457                 error "expect mode $old_dir_mode get $new_dir_mode"
16458
16459         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16460         [ "$old_file_mode" = "$new_file_mode" ] ||
16461                 error "expect mode $old_file_mode get $new_file_mode"
16462
16463         diff /etc/passwd ${migrate_dir}/$tfile ||
16464                 error "$tfile different after migration"
16465
16466         diff /etc/passwd ${other_dir}/luna ||
16467                 error "luna different after migration"
16468
16469         diff /etc/passwd ${migrate_dir}/sofia ||
16470                 error "sofia different after migration"
16471
16472         diff /etc/passwd ${other_dir}/zachary ||
16473                 error "zachary different after migration"
16474
16475         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16476                 error "${tfile}_ln different after migration"
16477
16478         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16479                 error "${tfile}_ln_other different after migration"
16480
16481         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16482         [ $stripe_count = 2 ] ||
16483                 error "dir strpe_count $d != 2 after migration."
16484
16485         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16486         [ $stripe_count = 2 ] ||
16487                 error "file strpe_count $d != 2 after migration."
16488
16489         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16490 }
16491 run_test 230b "migrate directory"
16492
16493 test_230c() {
16494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16495         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16496         remote_mds_nodsh && skip "remote MDS with nodsh"
16497         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16498                 skip "Need MDS version at least 2.11.52"
16499
16500         local MDTIDX=1
16501         local total=3
16502         local mdt_index
16503         local file
16504         local migrate_dir=$DIR/$tdir/migrate_dir
16505
16506         #If migrating directory fails in the middle, all entries of
16507         #the directory is still accessiable.
16508         test_mkdir $DIR/$tdir
16509         test_mkdir -i0 -c1 $migrate_dir
16510         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16511         stat $migrate_dir
16512         createmany -o $migrate_dir/f $total ||
16513                 error "create files under ${migrate_dir} failed"
16514
16515         # fail after migrating top dir, and this will fail only once, so the
16516         # first sub file migration will fail (currently f3), others succeed.
16517         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16518         do_facet mds1 lctl set_param fail_loc=0x1801
16519         local t=$(ls $migrate_dir | wc -l)
16520         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16521                 error "migrate should fail"
16522         local u=$(ls $migrate_dir | wc -l)
16523         [ "$u" == "$t" ] || error "$u != $t during migration"
16524
16525         # add new dir/file should succeed
16526         mkdir $migrate_dir/dir ||
16527                 error "mkdir failed under migrating directory"
16528         touch $migrate_dir/file ||
16529                 error "create file failed under migrating directory"
16530
16531         # add file with existing name should fail
16532         for file in $migrate_dir/f*; do
16533                 stat $file > /dev/null || error "stat $file failed"
16534                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16535                         error "open(O_CREAT|O_EXCL) $file should fail"
16536                 $MULTIOP $file m && error "create $file should fail"
16537                 touch $DIR/$tdir/remote_dir/$tfile ||
16538                         error "touch $tfile failed"
16539                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16540                         error "link $file should fail"
16541                 mdt_index=$($LFS getstripe -m $file)
16542                 if [ $mdt_index == 0 ]; then
16543                         # file failed to migrate is not allowed to rename to
16544                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16545                                 error "rename to $file should fail"
16546                 else
16547                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16548                                 error "rename to $file failed"
16549                 fi
16550                 echo hello >> $file || error "write $file failed"
16551         done
16552
16553         # resume migration with different options should fail
16554         $LFS migrate -m 0 $migrate_dir &&
16555                 error "migrate -m 0 $migrate_dir should fail"
16556
16557         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16558                 error "migrate -c 2 $migrate_dir should fail"
16559
16560         # resume migration should succeed
16561         $LFS migrate -m $MDTIDX $migrate_dir ||
16562                 error "migrate $migrate_dir failed"
16563
16564         echo "Finish migration, then checking.."
16565         for file in $(find $migrate_dir); do
16566                 mdt_index=$($LFS getstripe -m $file)
16567                 [ $mdt_index == $MDTIDX ] ||
16568                         error "$file is not on MDT${MDTIDX}"
16569         done
16570
16571         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16572 }
16573 run_test 230c "check directory accessiblity if migration failed"
16574
16575 test_230d() {
16576         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16577         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16578         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16579                 skip "Need MDS version at least 2.11.52"
16580         # LU-11235
16581         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16582
16583         local migrate_dir=$DIR/$tdir/migrate_dir
16584         local old_index
16585         local new_index
16586         local old_count
16587         local new_count
16588         local new_hash
16589         local mdt_index
16590         local i
16591         local j
16592
16593         old_index=$((RANDOM % MDSCOUNT))
16594         old_count=$((MDSCOUNT - old_index))
16595         new_index=$((RANDOM % MDSCOUNT))
16596         new_count=$((MDSCOUNT - new_index))
16597         new_hash="all_char"
16598
16599         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16600         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16601
16602         test_mkdir $DIR/$tdir
16603         test_mkdir -i $old_index -c $old_count $migrate_dir
16604
16605         for ((i=0; i<100; i++)); do
16606                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16607                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16608                         error "create files under remote dir failed $i"
16609         done
16610
16611         echo -n "Migrate from MDT$old_index "
16612         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16613         echo -n "to MDT$new_index"
16614         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16615         echo
16616
16617         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16618         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16619                 error "migrate remote dir error"
16620
16621         echo "Finish migration, then checking.."
16622         for file in $(find $migrate_dir); do
16623                 mdt_index=$($LFS getstripe -m $file)
16624                 if [ $mdt_index -lt $new_index ] ||
16625                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16626                         error "$file is on MDT$mdt_index"
16627                 fi
16628         done
16629
16630         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16631 }
16632 run_test 230d "check migrate big directory"
16633
16634 test_230e() {
16635         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16636         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16637         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16638                 skip "Need MDS version at least 2.11.52"
16639
16640         local i
16641         local j
16642         local a_fid
16643         local b_fid
16644
16645         mkdir -p $DIR/$tdir
16646         mkdir $DIR/$tdir/migrate_dir
16647         mkdir $DIR/$tdir/other_dir
16648         touch $DIR/$tdir/migrate_dir/a
16649         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16650         ls $DIR/$tdir/other_dir
16651
16652         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16653                 error "migrate dir fails"
16654
16655         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16656         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16657
16658         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16659         [ $mdt_index == 0 ] || error "a is not on MDT0"
16660
16661         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16662                 error "migrate dir fails"
16663
16664         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16665         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16666
16667         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16668         [ $mdt_index == 1 ] || error "a is not on MDT1"
16669
16670         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16671         [ $mdt_index == 1 ] || error "b is not on MDT1"
16672
16673         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16674         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16675
16676         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16677
16678         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16679 }
16680 run_test 230e "migrate mulitple local link files"
16681
16682 test_230f() {
16683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16684         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16685         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16686                 skip "Need MDS version at least 2.11.52"
16687
16688         local a_fid
16689         local ln_fid
16690
16691         mkdir -p $DIR/$tdir
16692         mkdir $DIR/$tdir/migrate_dir
16693         $LFS mkdir -i1 $DIR/$tdir/other_dir
16694         touch $DIR/$tdir/migrate_dir/a
16695         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16696         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16697         ls $DIR/$tdir/other_dir
16698
16699         # a should be migrated to MDT1, since no other links on MDT0
16700         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16701                 error "#1 migrate dir fails"
16702         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16703         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16704         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16705         [ $mdt_index == 1 ] || error "a is not on MDT1"
16706
16707         # a should stay on MDT1, because it is a mulitple link file
16708         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16709                 error "#2 migrate dir fails"
16710         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16711         [ $mdt_index == 1 ] || error "a is not on MDT1"
16712
16713         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16714                 error "#3 migrate dir fails"
16715
16716         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16717         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16718         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16719
16720         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16721         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16722
16723         # a should be migrated to MDT0, since no other links on MDT1
16724         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16725                 error "#4 migrate dir fails"
16726         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16727         [ $mdt_index == 0 ] || error "a is not on MDT0"
16728
16729         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16730 }
16731 run_test 230f "migrate mulitple remote link files"
16732
16733 test_230g() {
16734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16735         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16736         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16737                 skip "Need MDS version at least 2.11.52"
16738
16739         mkdir -p $DIR/$tdir/migrate_dir
16740
16741         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16742                 error "migrating dir to non-exist MDT succeeds"
16743         true
16744 }
16745 run_test 230g "migrate dir to non-exist MDT"
16746
16747 test_230h() {
16748         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16749         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16750         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16751                 skip "Need MDS version at least 2.11.52"
16752
16753         local mdt_index
16754
16755         mkdir -p $DIR/$tdir/migrate_dir
16756
16757         $LFS migrate -m1 $DIR &&
16758                 error "migrating mountpoint1 should fail"
16759
16760         $LFS migrate -m1 $DIR/$tdir/.. &&
16761                 error "migrating mountpoint2 should fail"
16762
16763         # same as mv
16764         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16765                 error "migrating $tdir/migrate_dir/.. should fail"
16766
16767         true
16768 }
16769 run_test 230h "migrate .. and root"
16770
16771 test_230i() {
16772         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16773         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16774         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16775                 skip "Need MDS version at least 2.11.52"
16776
16777         mkdir -p $DIR/$tdir/migrate_dir
16778
16779         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16780                 error "migration fails with a tailing slash"
16781
16782         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16783                 error "migration fails with two tailing slashes"
16784 }
16785 run_test 230i "lfs migrate -m tolerates trailing slashes"
16786
16787 test_230j() {
16788         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16789         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16790                 skip "Need MDS version at least 2.11.52"
16791
16792         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16793         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16794                 error "create $tfile failed"
16795         cat /etc/passwd > $DIR/$tdir/$tfile
16796
16797         $LFS migrate -m 1 $DIR/$tdir
16798
16799         cmp /etc/passwd $DIR/$tdir/$tfile ||
16800                 error "DoM file mismatch after migration"
16801 }
16802 run_test 230j "DoM file data not changed after dir migration"
16803
16804 test_230k() {
16805         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16806         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16807                 skip "Need MDS version at least 2.11.56"
16808
16809         local total=20
16810         local files_on_starting_mdt=0
16811
16812         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16813         $LFS getdirstripe $DIR/$tdir
16814         for i in $(seq $total); do
16815                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16816                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16817                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16818         done
16819
16820         echo "$files_on_starting_mdt files on MDT0"
16821
16822         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16823         $LFS getdirstripe $DIR/$tdir
16824
16825         files_on_starting_mdt=0
16826         for i in $(seq $total); do
16827                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16828                         error "file $tfile.$i mismatch after migration"
16829                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16830                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16831         done
16832
16833         echo "$files_on_starting_mdt files on MDT1 after migration"
16834         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16835
16836         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16837         $LFS getdirstripe $DIR/$tdir
16838
16839         files_on_starting_mdt=0
16840         for i in $(seq $total); do
16841                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16842                         error "file $tfile.$i mismatch after 2nd migration"
16843                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16844                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16845         done
16846
16847         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16848         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16849
16850         true
16851 }
16852 run_test 230k "file data not changed after dir migration"
16853
16854 test_230l() {
16855         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16856         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16857                 skip "Need MDS version at least 2.11.56"
16858
16859         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16860         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16861                 error "create files under remote dir failed $i"
16862         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16863 }
16864 run_test 230l "readdir between MDTs won't crash"
16865
16866 test_231a()
16867 {
16868         # For simplicity this test assumes that max_pages_per_rpc
16869         # is the same across all OSCs
16870         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16871         local bulk_size=$((max_pages * PAGE_SIZE))
16872         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16873                                        head -n 1)
16874
16875         mkdir -p $DIR/$tdir
16876         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16877                 error "failed to set stripe with -S ${brw_size}M option"
16878
16879         # clear the OSC stats
16880         $LCTL set_param osc.*.stats=0 &>/dev/null
16881         stop_writeback
16882
16883         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16884         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16885                 oflag=direct &>/dev/null || error "dd failed"
16886
16887         sync; sleep 1; sync # just to be safe
16888         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16889         if [ x$nrpcs != "x1" ]; then
16890                 $LCTL get_param osc.*.stats
16891                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16892         fi
16893
16894         start_writeback
16895         # Drop the OSC cache, otherwise we will read from it
16896         cancel_lru_locks osc
16897
16898         # clear the OSC stats
16899         $LCTL set_param osc.*.stats=0 &>/dev/null
16900
16901         # Client reads $bulk_size.
16902         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16903                 iflag=direct &>/dev/null || error "dd failed"
16904
16905         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16906         if [ x$nrpcs != "x1" ]; then
16907                 $LCTL get_param osc.*.stats
16908                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16909         fi
16910 }
16911 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16912
16913 test_231b() {
16914         mkdir -p $DIR/$tdir
16915         local i
16916         for i in {0..1023}; do
16917                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16918                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16919                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16920         done
16921         sync
16922 }
16923 run_test 231b "must not assert on fully utilized OST request buffer"
16924
16925 test_232a() {
16926         mkdir -p $DIR/$tdir
16927         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16928
16929         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16930         do_facet ost1 $LCTL set_param fail_loc=0x31c
16931
16932         # ignore dd failure
16933         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16934
16935         do_facet ost1 $LCTL set_param fail_loc=0
16936         umount_client $MOUNT || error "umount failed"
16937         mount_client $MOUNT || error "mount failed"
16938         stop ost1 || error "cannot stop ost1"
16939         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16940 }
16941 run_test 232a "failed lock should not block umount"
16942
16943 test_232b() {
16944         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16945                 skip "Need MDS version at least 2.10.58"
16946
16947         mkdir -p $DIR/$tdir
16948         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16949         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16950         sync
16951         cancel_lru_locks osc
16952
16953         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16954         do_facet ost1 $LCTL set_param fail_loc=0x31c
16955
16956         # ignore failure
16957         $LFS data_version $DIR/$tdir/$tfile || true
16958
16959         do_facet ost1 $LCTL set_param fail_loc=0
16960         umount_client $MOUNT || error "umount failed"
16961         mount_client $MOUNT || error "mount failed"
16962         stop ost1 || error "cannot stop ost1"
16963         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16964 }
16965 run_test 232b "failed data version lock should not block umount"
16966
16967 test_233a() {
16968         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16969                 skip "Need MDS version at least 2.3.64"
16970         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16971
16972         local fid=$($LFS path2fid $MOUNT)
16973
16974         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16975                 error "cannot access $MOUNT using its FID '$fid'"
16976 }
16977 run_test 233a "checking that OBF of the FS root succeeds"
16978
16979 test_233b() {
16980         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16981                 skip "Need MDS version at least 2.5.90"
16982         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16983
16984         local fid=$($LFS path2fid $MOUNT/.lustre)
16985
16986         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16987                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16988
16989         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16990         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16991                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16992 }
16993 run_test 233b "checking that OBF of the FS .lustre succeeds"
16994
16995 test_234() {
16996         local p="$TMP/sanityN-$TESTNAME.parameters"
16997         save_lustre_params client "llite.*.xattr_cache" > $p
16998         lctl set_param llite.*.xattr_cache 1 ||
16999                 skip_env "xattr cache is not supported"
17000
17001         mkdir -p $DIR/$tdir || error "mkdir failed"
17002         touch $DIR/$tdir/$tfile || error "touch failed"
17003         # OBD_FAIL_LLITE_XATTR_ENOMEM
17004         $LCTL set_param fail_loc=0x1405
17005         getfattr -n user.attr $DIR/$tdir/$tfile &&
17006                 error "getfattr should have failed with ENOMEM"
17007         $LCTL set_param fail_loc=0x0
17008         rm -rf $DIR/$tdir
17009
17010         restore_lustre_params < $p
17011         rm -f $p
17012 }
17013 run_test 234 "xattr cache should not crash on ENOMEM"
17014
17015 test_235() {
17016         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
17017                 skip "Need MDS version at least 2.4.52"
17018
17019         flock_deadlock $DIR/$tfile
17020         local RC=$?
17021         case $RC in
17022                 0)
17023                 ;;
17024                 124) error "process hangs on a deadlock"
17025                 ;;
17026                 *) error "error executing flock_deadlock $DIR/$tfile"
17027                 ;;
17028         esac
17029 }
17030 run_test 235 "LU-1715: flock deadlock detection does not work properly"
17031
17032 #LU-2935
17033 test_236() {
17034         check_swap_layouts_support
17035
17036         local ref1=/etc/passwd
17037         local ref2=/etc/group
17038         local file1=$DIR/$tdir/f1
17039         local file2=$DIR/$tdir/f2
17040
17041         test_mkdir -c1 $DIR/$tdir
17042         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
17043         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
17044         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
17045         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
17046         local fd=$(free_fd)
17047         local cmd="exec $fd<>$file2"
17048         eval $cmd
17049         rm $file2
17050         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
17051                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
17052         cmd="exec $fd>&-"
17053         eval $cmd
17054         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
17055
17056         #cleanup
17057         rm -rf $DIR/$tdir
17058 }
17059 run_test 236 "Layout swap on open unlinked file"
17060
17061 # LU-4659 linkea consistency
17062 test_238() {
17063         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
17064                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
17065                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
17066                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
17067
17068         touch $DIR/$tfile
17069         ln $DIR/$tfile $DIR/$tfile.lnk
17070         touch $DIR/$tfile.new
17071         mv $DIR/$tfile.new $DIR/$tfile
17072         local fid1=$($LFS path2fid $DIR/$tfile)
17073         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
17074         local path1=$($LFS fid2path $FSNAME "$fid1")
17075         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
17076         local path2=$($LFS fid2path $FSNAME "$fid2")
17077         [ $tfile.lnk == $path2 ] ||
17078                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
17079         rm -f $DIR/$tfile*
17080 }
17081 run_test 238 "Verify linkea consistency"
17082
17083 test_239A() { # was test_239
17084         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
17085                 skip "Need MDS version at least 2.5.60"
17086
17087         local list=$(comma_list $(mdts_nodes))
17088
17089         mkdir -p $DIR/$tdir
17090         createmany -o $DIR/$tdir/f- 5000
17091         unlinkmany $DIR/$tdir/f- 5000
17092         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
17093                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
17094         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
17095                         osp.*MDT*.sync_in_flight" | calc_sum)
17096         [ "$changes" -eq 0 ] || error "$changes not synced"
17097 }
17098 run_test 239A "osp_sync test"
17099
17100 test_239a() { #LU-5297
17101         remote_mds_nodsh && skip "remote MDS with nodsh"
17102
17103         touch $DIR/$tfile
17104         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
17105         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
17106         chgrp $RUNAS_GID $DIR/$tfile
17107         wait_delete_completed
17108 }
17109 run_test 239a "process invalid osp sync record correctly"
17110
17111 test_239b() { #LU-5297
17112         remote_mds_nodsh && skip "remote MDS with nodsh"
17113
17114         touch $DIR/$tfile1
17115         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
17116         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
17117         chgrp $RUNAS_GID $DIR/$tfile1
17118         wait_delete_completed
17119         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
17120         touch $DIR/$tfile2
17121         chgrp $RUNAS_GID $DIR/$tfile2
17122         wait_delete_completed
17123 }
17124 run_test 239b "process osp sync record with ENOMEM error correctly"
17125
17126 test_240() {
17127         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
17128         remote_mds_nodsh && skip "remote MDS with nodsh"
17129
17130         mkdir -p $DIR/$tdir
17131
17132         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
17133                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
17134         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
17135                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
17136
17137         umount_client $MOUNT || error "umount failed"
17138         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
17139         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
17140         mount_client $MOUNT || error "failed to mount client"
17141
17142         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
17143         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
17144 }
17145 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
17146
17147 test_241_bio() {
17148         local count=$1
17149         local bsize=$2
17150
17151         for LOOP in $(seq $count); do
17152                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
17153                 cancel_lru_locks $OSC || true
17154         done
17155 }
17156
17157 test_241_dio() {
17158         local count=$1
17159         local bsize=$2
17160
17161         for LOOP in $(seq $1); do
17162                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
17163                         2>/dev/null
17164         done
17165 }
17166
17167 test_241a() { # was test_241
17168         local bsize=$PAGE_SIZE
17169
17170         (( bsize < 40960 )) && bsize=40960
17171         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17172         ls -la $DIR/$tfile
17173         cancel_lru_locks $OSC
17174         test_241_bio 1000 $bsize &
17175         PID=$!
17176         test_241_dio 1000 $bsize
17177         wait $PID
17178 }
17179 run_test 241a "bio vs dio"
17180
17181 test_241b() {
17182         local bsize=$PAGE_SIZE
17183
17184         (( bsize < 40960 )) && bsize=40960
17185         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
17186         ls -la $DIR/$tfile
17187         test_241_dio 1000 $bsize &
17188         PID=$!
17189         test_241_dio 1000 $bsize
17190         wait $PID
17191 }
17192 run_test 241b "dio vs dio"
17193
17194 test_242() {
17195         remote_mds_nodsh && skip "remote MDS with nodsh"
17196
17197         mkdir -p $DIR/$tdir
17198         touch $DIR/$tdir/$tfile
17199
17200         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17201         do_facet mds1 lctl set_param fail_loc=0x105
17202         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17203
17204         do_facet mds1 lctl set_param fail_loc=0
17205         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17206 }
17207 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17208
17209 test_243()
17210 {
17211         test_mkdir $DIR/$tdir
17212         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17213 }
17214 run_test 243 "various group lock tests"
17215
17216 test_244a()
17217 {
17218         test_mkdir $DIR/$tdir
17219         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17220         sendfile_grouplock $DIR/$tdir/$tfile || \
17221                 error "sendfile+grouplock failed"
17222         rm -rf $DIR/$tdir
17223 }
17224 run_test 244a "sendfile with group lock tests"
17225
17226 test_244b()
17227 {
17228         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17229
17230         local threads=50
17231         local size=$((1024*1024))
17232
17233         test_mkdir $DIR/$tdir
17234         for i in $(seq 1 $threads); do
17235                 local file=$DIR/$tdir/file_$((i / 10))
17236                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17237                 local pids[$i]=$!
17238         done
17239         for i in $(seq 1 $threads); do
17240                 wait ${pids[$i]}
17241         done
17242 }
17243 run_test 244b "multi-threaded write with group lock"
17244
17245 test_245() {
17246         local flagname="multi_mod_rpcs"
17247         local connect_data_name="max_mod_rpcs"
17248         local out
17249
17250         # check if multiple modify RPCs flag is set
17251         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17252                 grep "connect_flags:")
17253         echo "$out"
17254
17255         echo "$out" | grep -qw $flagname
17256         if [ $? -ne 0 ]; then
17257                 echo "connect flag $flagname is not set"
17258                 return
17259         fi
17260
17261         # check if multiple modify RPCs data is set
17262         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17263         echo "$out"
17264
17265         echo "$out" | grep -qw $connect_data_name ||
17266                 error "import should have connect data $connect_data_name"
17267 }
17268 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17269
17270 test_246() { # LU-7371
17271         remote_ost_nodsh && skip "remote OST with nodsh"
17272         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
17273                 skip "Need OST version >= 2.7.62"
17274
17275         do_facet ost1 $LCTL set_param fail_val=4095
17276 #define OBD_FAIL_OST_READ_SIZE          0x234
17277         do_facet ost1 $LCTL set_param fail_loc=0x234
17278         $LFS setstripe $DIR/$tfile -i 0 -c 1
17279         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
17280         cancel_lru_locks $FSNAME-OST0000
17281         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
17282 }
17283 run_test 246 "Read file of size 4095 should return right length"
17284
17285 cleanup_247() {
17286         local submount=$1
17287
17288         trap 0
17289         umount_client $submount
17290         rmdir $submount
17291 }
17292
17293 test_247a() {
17294         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17295                 grep -q subtree ||
17296                 skip_env "Fileset feature is not supported"
17297
17298         local submount=${MOUNT}_$tdir
17299
17300         mkdir $MOUNT/$tdir
17301         mkdir -p $submount || error "mkdir $submount failed"
17302         FILESET="$FILESET/$tdir" mount_client $submount ||
17303                 error "mount $submount failed"
17304         trap "cleanup_247 $submount" EXIT
17305         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17306         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17307                 error "read $MOUNT/$tdir/$tfile failed"
17308         cleanup_247 $submount
17309 }
17310 run_test 247a "mount subdir as fileset"
17311
17312 test_247b() {
17313         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17314                 skip_env "Fileset feature is not supported"
17315
17316         local submount=${MOUNT}_$tdir
17317
17318         rm -rf $MOUNT/$tdir
17319         mkdir -p $submount || error "mkdir $submount failed"
17320         SKIP_FILESET=1
17321         FILESET="$FILESET/$tdir" mount_client $submount &&
17322                 error "mount $submount should fail"
17323         rmdir $submount
17324 }
17325 run_test 247b "mount subdir that dose not exist"
17326
17327 test_247c() {
17328         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17329                 skip_env "Fileset feature is not supported"
17330
17331         local submount=${MOUNT}_$tdir
17332
17333         mkdir -p $MOUNT/$tdir/dir1
17334         mkdir -p $submount || error "mkdir $submount failed"
17335         trap "cleanup_247 $submount" EXIT
17336         FILESET="$FILESET/$tdir" mount_client $submount ||
17337                 error "mount $submount failed"
17338         local fid=$($LFS path2fid $MOUNT/)
17339         $LFS fid2path $submount $fid && error "fid2path should fail"
17340         cleanup_247 $submount
17341 }
17342 run_test 247c "running fid2path outside root"
17343
17344 test_247d() {
17345         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17346                 skip "Fileset feature is not supported"
17347
17348         local submount=${MOUNT}_$tdir
17349
17350         mkdir -p $MOUNT/$tdir/dir1
17351         mkdir -p $submount || error "mkdir $submount failed"
17352         FILESET="$FILESET/$tdir" mount_client $submount ||
17353                 error "mount $submount failed"
17354         trap "cleanup_247 $submount" EXIT
17355         local fid=$($LFS path2fid $submount/dir1)
17356         $LFS fid2path $submount $fid || error "fid2path should succeed"
17357         cleanup_247 $submount
17358 }
17359 run_test 247d "running fid2path inside root"
17360
17361 # LU-8037
17362 test_247e() {
17363         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17364                 grep -q subtree ||
17365                 skip "Fileset feature is not supported"
17366
17367         local submount=${MOUNT}_$tdir
17368
17369         mkdir $MOUNT/$tdir
17370         mkdir -p $submount || error "mkdir $submount failed"
17371         FILESET="$FILESET/.." mount_client $submount &&
17372                 error "mount $submount should fail"
17373         rmdir $submount
17374 }
17375 run_test 247e "mount .. as fileset"
17376
17377 test_248() {
17378         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17379         [ -z "$fast_read_sav" ] && skip "no fast read support"
17380
17381         # create a large file for fast read verification
17382         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17383
17384         # make sure the file is created correctly
17385         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17386                 { rm -f $DIR/$tfile; skip "file creation error"; }
17387
17388         echo "Test 1: verify that fast read is 4 times faster on cache read"
17389
17390         # small read with fast read enabled
17391         $LCTL set_param -n llite.*.fast_read=1
17392         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17393                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17394                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17395         # small read with fast read disabled
17396         $LCTL set_param -n llite.*.fast_read=0
17397         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17398                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17399                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17400
17401         # verify that fast read is 4 times faster for cache read
17402         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17403                 error_not_in_vm "fast read was not 4 times faster: " \
17404                            "$t_fast vs $t_slow"
17405
17406         echo "Test 2: verify the performance between big and small read"
17407         $LCTL set_param -n llite.*.fast_read=1
17408
17409         # 1k non-cache read
17410         cancel_lru_locks osc
17411         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17412                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17413                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17414
17415         # 1M non-cache read
17416         cancel_lru_locks osc
17417         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17418                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17419                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17420
17421         # verify that big IO is not 4 times faster than small IO
17422         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17423                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17424
17425         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17426         rm -f $DIR/$tfile
17427 }
17428 run_test 248 "fast read verification"
17429
17430 test_249() { # LU-7890
17431         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17432                 skip "Need at least version 2.8.54"
17433
17434         rm -f $DIR/$tfile
17435         $LFS setstripe -c 1 $DIR/$tfile
17436         # Offset 2T == 4k * 512M
17437         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17438                 error "dd to 2T offset failed"
17439 }
17440 run_test 249 "Write above 2T file size"
17441
17442 test_250() {
17443         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17444          && skip "no 16TB file size limit on ZFS"
17445
17446         $LFS setstripe -c 1 $DIR/$tfile
17447         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17448         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17449         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17450         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17451                 conv=notrunc,fsync && error "append succeeded"
17452         return 0
17453 }
17454 run_test 250 "Write above 16T limit"
17455
17456 test_251() {
17457         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17458
17459         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17460         #Skip once - writing the first stripe will succeed
17461         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17462         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17463                 error "short write happened"
17464
17465         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17466         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17467                 error "short read happened"
17468
17469         rm -f $DIR/$tfile
17470 }
17471 run_test 251 "Handling short read and write correctly"
17472
17473 test_252() {
17474         remote_mds_nodsh && skip "remote MDS with nodsh"
17475         remote_ost_nodsh && skip "remote OST with nodsh"
17476         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17477                 skip_env "ldiskfs only test"
17478         fi
17479
17480         local tgt
17481         local dev
17482         local out
17483         local uuid
17484         local num
17485         local gen
17486
17487         # check lr_reader on OST0000
17488         tgt=ost1
17489         dev=$(facet_device $tgt)
17490         out=$(do_facet $tgt $LR_READER $dev)
17491         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17492         echo "$out"
17493         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17494         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17495                 error "Invalid uuid returned by $LR_READER on target $tgt"
17496         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17497
17498         # check lr_reader -c on MDT0000
17499         tgt=mds1
17500         dev=$(facet_device $tgt)
17501         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17502                 skip "$LR_READER does not support additional options"
17503         fi
17504         out=$(do_facet $tgt $LR_READER -c $dev)
17505         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17506         echo "$out"
17507         num=$(echo "$out" | grep -c "mdtlov")
17508         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17509                 error "Invalid number of mdtlov clients returned by $LR_READER"
17510         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17511
17512         # check lr_reader -cr on MDT0000
17513         out=$(do_facet $tgt $LR_READER -cr $dev)
17514         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17515         echo "$out"
17516         echo "$out" | grep -q "^reply_data:$" ||
17517                 error "$LR_READER should have returned 'reply_data' section"
17518         num=$(echo "$out" | grep -c "client_generation")
17519         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17520 }
17521 run_test 252 "check lr_reader tool"
17522
17523 test_253() {
17524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17525         remote_mds_nodsh && skip "remote MDS with nodsh"
17526         remote_mgs_nodsh && skip "remote MGS with nodsh"
17527
17528         local ostidx=0
17529         local rc=0
17530         local ost_name=$(ostname_from_index $ostidx)
17531
17532         # on the mdt's osc
17533         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17534         do_facet $SINGLEMDS $LCTL get_param -n \
17535                 osp.$mdtosc_proc1.reserved_mb_high ||
17536                 skip  "remote MDS does not support reserved_mb_high"
17537
17538         rm -rf $DIR/$tdir
17539         wait_mds_ost_sync
17540         wait_delete_completed
17541         mkdir $DIR/$tdir
17542
17543         pool_add $TESTNAME || error "Pool creation failed"
17544         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17545
17546         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17547                 error "Setstripe failed"
17548
17549         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17550
17551         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17552                     grep "watermarks")
17553         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17554
17555         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17556                         osp.$mdtosc_proc1.prealloc_status)
17557         echo "prealloc_status $oa_status"
17558
17559         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17560                 error "File creation should fail"
17561
17562         #object allocation was stopped, but we still able to append files
17563         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17564                 oflag=append || error "Append failed"
17565
17566         rm -f $DIR/$tdir/$tfile.0
17567
17568         # For this test, we want to delete the files we created to go out of
17569         # space but leave the watermark, so we remain nearly out of space
17570         ost_watermarks_enospc_delete_files $tfile $ostidx
17571
17572         wait_delete_completed
17573
17574         sleep_maxage
17575
17576         for i in $(seq 10 12); do
17577                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17578                         2>/dev/null || error "File creation failed after rm"
17579         done
17580
17581         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17582                         osp.$mdtosc_proc1.prealloc_status)
17583         echo "prealloc_status $oa_status"
17584
17585         if (( oa_status != 0 )); then
17586                 error "Object allocation still disable after rm"
17587         fi
17588 }
17589 run_test 253 "Check object allocation limit"
17590
17591 test_254() {
17592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17593         remote_mds_nodsh && skip "remote MDS with nodsh"
17594         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17595                 skip "MDS does not support changelog_size"
17596
17597         local cl_user
17598         local MDT0=$(facet_svc $SINGLEMDS)
17599
17600         changelog_register || error "changelog_register failed"
17601
17602         changelog_clear 0 || error "changelog_clear failed"
17603
17604         local size1=$(do_facet $SINGLEMDS \
17605                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17606         echo "Changelog size $size1"
17607
17608         rm -rf $DIR/$tdir
17609         $LFS mkdir -i 0 $DIR/$tdir
17610         # change something
17611         mkdir -p $DIR/$tdir/pics/2008/zachy
17612         touch $DIR/$tdir/pics/2008/zachy/timestamp
17613         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17614         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17615         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17616         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17617         rm $DIR/$tdir/pics/desktop.jpg
17618
17619         local size2=$(do_facet $SINGLEMDS \
17620                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17621         echo "Changelog size after work $size2"
17622
17623         (( $size2 > $size1 )) ||
17624                 error "new Changelog size=$size2 less than old size=$size1"
17625 }
17626 run_test 254 "Check changelog size"
17627
17628 ladvise_no_type()
17629 {
17630         local type=$1
17631         local file=$2
17632
17633         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17634                 awk -F: '{print $2}' | grep $type > /dev/null
17635         if [ $? -ne 0 ]; then
17636                 return 0
17637         fi
17638         return 1
17639 }
17640
17641 ladvise_no_ioctl()
17642 {
17643         local file=$1
17644
17645         lfs ladvise -a willread $file > /dev/null 2>&1
17646         if [ $? -eq 0 ]; then
17647                 return 1
17648         fi
17649
17650         lfs ladvise -a willread $file 2>&1 |
17651                 grep "Inappropriate ioctl for device" > /dev/null
17652         if [ $? -eq 0 ]; then
17653                 return 0
17654         fi
17655         return 1
17656 }
17657
17658 percent() {
17659         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17660 }
17661
17662 # run a random read IO workload
17663 # usage: random_read_iops <filename> <filesize> <iosize>
17664 random_read_iops() {
17665         local file=$1
17666         local fsize=$2
17667         local iosize=${3:-4096}
17668
17669         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17670                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17671 }
17672
17673 drop_file_oss_cache() {
17674         local file="$1"
17675         local nodes="$2"
17676
17677         $LFS ladvise -a dontneed $file 2>/dev/null ||
17678                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17679 }
17680
17681 ladvise_willread_performance()
17682 {
17683         local repeat=10
17684         local average_origin=0
17685         local average_cache=0
17686         local average_ladvise=0
17687
17688         for ((i = 1; i <= $repeat; i++)); do
17689                 echo "Iter $i/$repeat: reading without willread hint"
17690                 cancel_lru_locks osc
17691                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17692                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17693                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17694                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17695
17696                 cancel_lru_locks osc
17697                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17698                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17699                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17700
17701                 cancel_lru_locks osc
17702                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17703                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17704                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17705                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17706                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17707         done
17708         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17709         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17710         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17711
17712         speedup_cache=$(percent $average_cache $average_origin)
17713         speedup_ladvise=$(percent $average_ladvise $average_origin)
17714
17715         echo "Average uncached read: $average_origin"
17716         echo "Average speedup with OSS cached read: " \
17717                 "$average_cache = +$speedup_cache%"
17718         echo "Average speedup with ladvise willread: " \
17719                 "$average_ladvise = +$speedup_ladvise%"
17720
17721         local lowest_speedup=20
17722         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17723                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17724                         "got $average_cache%. Skipping ladvise willread check."
17725                 return 0
17726         fi
17727
17728         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17729         # it is still good to run until then to exercise 'ladvise willread'
17730         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17731                 [ "$ost1_FSTYPE" = "zfs" ] &&
17732                 echo "osd-zfs does not support dontneed or drop_caches" &&
17733                 return 0
17734
17735         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17736         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17737                 error_not_in_vm "Speedup with willread is less than " \
17738                         "$lowest_speedup%, got $average_ladvise%"
17739 }
17740
17741 test_255a() {
17742         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17743                 skip "lustre < 2.8.54 does not support ladvise "
17744         remote_ost_nodsh && skip "remote OST with nodsh"
17745
17746         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17747
17748         ladvise_no_type willread $DIR/$tfile &&
17749                 skip "willread ladvise is not supported"
17750
17751         ladvise_no_ioctl $DIR/$tfile &&
17752                 skip "ladvise ioctl is not supported"
17753
17754         local size_mb=100
17755         local size=$((size_mb * 1048576))
17756         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17757                 error "dd to $DIR/$tfile failed"
17758
17759         lfs ladvise -a willread $DIR/$tfile ||
17760                 error "Ladvise failed with no range argument"
17761
17762         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17763                 error "Ladvise failed with no -l or -e argument"
17764
17765         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17766                 error "Ladvise failed with only -e argument"
17767
17768         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17769                 error "Ladvise failed with only -l argument"
17770
17771         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17772                 error "End offset should not be smaller than start offset"
17773
17774         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17775                 error "End offset should not be equal to start offset"
17776
17777         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17778                 error "Ladvise failed with overflowing -s argument"
17779
17780         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17781                 error "Ladvise failed with overflowing -e argument"
17782
17783         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17784                 error "Ladvise failed with overflowing -l argument"
17785
17786         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17787                 error "Ladvise succeeded with conflicting -l and -e arguments"
17788
17789         echo "Synchronous ladvise should wait"
17790         local delay=4
17791 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17792         do_nodes $(comma_list $(osts_nodes)) \
17793                 $LCTL set_param fail_val=$delay fail_loc=0x237
17794
17795         local start_ts=$SECONDS
17796         lfs ladvise -a willread $DIR/$tfile ||
17797                 error "Ladvise failed with no range argument"
17798         local end_ts=$SECONDS
17799         local inteval_ts=$((end_ts - start_ts))
17800
17801         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17802                 error "Synchronous advice didn't wait reply"
17803         fi
17804
17805         echo "Asynchronous ladvise shouldn't wait"
17806         local start_ts=$SECONDS
17807         lfs ladvise -a willread -b $DIR/$tfile ||
17808                 error "Ladvise failed with no range argument"
17809         local end_ts=$SECONDS
17810         local inteval_ts=$((end_ts - start_ts))
17811
17812         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17813                 error "Asynchronous advice blocked"
17814         fi
17815
17816         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17817         ladvise_willread_performance
17818 }
17819 run_test 255a "check 'lfs ladvise -a willread'"
17820
17821 facet_meminfo() {
17822         local facet=$1
17823         local info=$2
17824
17825         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17826 }
17827
17828 test_255b() {
17829         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17830                 skip "lustre < 2.8.54 does not support ladvise "
17831         remote_ost_nodsh && skip "remote OST with nodsh"
17832
17833         lfs setstripe -c 1 -i 0 $DIR/$tfile
17834
17835         ladvise_no_type dontneed $DIR/$tfile &&
17836                 skip "dontneed ladvise is not supported"
17837
17838         ladvise_no_ioctl $DIR/$tfile &&
17839                 skip "ladvise ioctl is not supported"
17840
17841         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17842                 [ "$ost1_FSTYPE" = "zfs" ] &&
17843                 skip "zfs-osd does not support 'ladvise dontneed'"
17844
17845         local size_mb=100
17846         local size=$((size_mb * 1048576))
17847         # In order to prevent disturbance of other processes, only check 3/4
17848         # of the memory usage
17849         local kibibytes=$((size_mb * 1024 * 3 / 4))
17850
17851         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17852                 error "dd to $DIR/$tfile failed"
17853
17854         #force write to complete before dropping OST cache & checking memory
17855         sync
17856
17857         local total=$(facet_meminfo ost1 MemTotal)
17858         echo "Total memory: $total KiB"
17859
17860         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17861         local before_read=$(facet_meminfo ost1 Cached)
17862         echo "Cache used before read: $before_read KiB"
17863
17864         lfs ladvise -a willread $DIR/$tfile ||
17865                 error "Ladvise willread failed"
17866         local after_read=$(facet_meminfo ost1 Cached)
17867         echo "Cache used after read: $after_read KiB"
17868
17869         lfs ladvise -a dontneed $DIR/$tfile ||
17870                 error "Ladvise dontneed again failed"
17871         local no_read=$(facet_meminfo ost1 Cached)
17872         echo "Cache used after dontneed ladvise: $no_read KiB"
17873
17874         if [ $total -lt $((before_read + kibibytes)) ]; then
17875                 echo "Memory is too small, abort checking"
17876                 return 0
17877         fi
17878
17879         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17880                 error "Ladvise willread should use more memory" \
17881                         "than $kibibytes KiB"
17882         fi
17883
17884         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17885                 error "Ladvise dontneed should release more memory" \
17886                         "than $kibibytes KiB"
17887         fi
17888 }
17889 run_test 255b "check 'lfs ladvise -a dontneed'"
17890
17891 test_255c() {
17892         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17893                 skip "lustre < 2.10.50 does not support lockahead"
17894
17895         local count
17896         local new_count
17897         local difference
17898         local i
17899         local rc
17900
17901         test_mkdir -p $DIR/$tdir
17902         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17903
17904         #test 10 returns only success/failure
17905         i=10
17906         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17907         rc=$?
17908         if [ $rc -eq 255 ]; then
17909                 error "Ladvise test${i} failed, ${rc}"
17910         fi
17911
17912         #test 11 counts lock enqueue requests, all others count new locks
17913         i=11
17914         count=$(do_facet ost1 \
17915                 $LCTL get_param -n ost.OSS.ost.stats)
17916         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17917
17918         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17919         rc=$?
17920         if [ $rc -eq 255 ]; then
17921                 error "Ladvise test${i} failed, ${rc}"
17922         fi
17923
17924         new_count=$(do_facet ost1 \
17925                 $LCTL get_param -n ost.OSS.ost.stats)
17926         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17927                    awk '{ print $2 }')
17928
17929         difference="$((new_count - count))"
17930         if [ $difference -ne $rc ]; then
17931                 error "Ladvise test${i}, bad enqueue count, returned " \
17932                       "${rc}, actual ${difference}"
17933         fi
17934
17935         for i in $(seq 12 21); do
17936                 # If we do not do this, we run the risk of having too many
17937                 # locks and starting lock cancellation while we are checking
17938                 # lock counts.
17939                 cancel_lru_locks osc
17940
17941                 count=$($LCTL get_param -n \
17942                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17943
17944                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17945                 rc=$?
17946                 if [ $rc -eq 255 ]; then
17947                         error "Ladvise test ${i} failed, ${rc}"
17948                 fi
17949
17950                 new_count=$($LCTL get_param -n \
17951                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17952                 difference="$((new_count - count))"
17953
17954                 # Test 15 output is divided by 100 to map down to valid return
17955                 if [ $i -eq 15 ]; then
17956                         rc="$((rc * 100))"
17957                 fi
17958
17959                 if [ $difference -ne $rc ]; then
17960                         error "Ladvise test ${i}, bad lock count, returned " \
17961                               "${rc}, actual ${difference}"
17962                 fi
17963         done
17964
17965         #test 22 returns only success/failure
17966         i=22
17967         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17968         rc=$?
17969         if [ $rc -eq 255 ]; then
17970                 error "Ladvise test${i} failed, ${rc}"
17971         fi
17972 }
17973 run_test 255c "suite of ladvise lockahead tests"
17974
17975 test_256() {
17976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17977         remote_mds_nodsh && skip "remote MDS with nodsh"
17978         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17979         changelog_users $SINGLEMDS | grep "^cl" &&
17980                 skip "active changelog user"
17981
17982         local cl_user
17983         local cat_sl
17984         local mdt_dev
17985
17986         mdt_dev=$(mdsdevname 1)
17987         echo $mdt_dev
17988
17989         changelog_register || error "changelog_register failed"
17990
17991         rm -rf $DIR/$tdir
17992         mkdir -p $DIR/$tdir
17993
17994         changelog_clear 0 || error "changelog_clear failed"
17995
17996         # change something
17997         touch $DIR/$tdir/{1..10}
17998
17999         # stop the MDT
18000         stop $SINGLEMDS || error "Fail to stop MDT"
18001
18002         # remount the MDT
18003
18004         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
18005
18006         #after mount new plainllog is used
18007         touch $DIR/$tdir/{11..19}
18008         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
18009         stack_trap "rm -f $tmpfile"
18010         cat_sl=$(do_facet $SINGLEMDS "sync; \
18011                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18012                  llog_reader $tmpfile | grep -c type=1064553b")
18013         do_facet $SINGLEMDS llog_reader $tmpfile
18014
18015         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
18016
18017         changelog_clear 0 || error "changelog_clear failed"
18018
18019         cat_sl=$(do_facet $SINGLEMDS "sync; \
18020                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
18021                  llog_reader $tmpfile | grep -c type=1064553b")
18022
18023         if (( cat_sl == 2 )); then
18024                 error "Empty plain llog was not deleted from changelog catalog"
18025         elif (( cat_sl != 1 )); then
18026                 error "Active plain llog shouldn't be deleted from catalog"
18027         fi
18028 }
18029 run_test 256 "Check llog delete for empty and not full state"
18030
18031 test_257() {
18032         remote_mds_nodsh && skip "remote MDS with nodsh"
18033         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
18034                 skip "Need MDS version at least 2.8.55"
18035
18036         test_mkdir $DIR/$tdir
18037
18038         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
18039                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
18040         stat $DIR/$tdir
18041
18042 #define OBD_FAIL_MDS_XATTR_REP                  0x161
18043         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18044         local facet=mds$((mdtidx + 1))
18045         set_nodes_failloc $(facet_active_host $facet) 0x80000161
18046         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
18047
18048         stop $facet || error "stop MDS failed"
18049         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
18050                 error "start MDS fail"
18051         wait_recovery_complete $facet
18052 }
18053 run_test 257 "xattr locks are not lost"
18054
18055 # Verify we take the i_mutex when security requires it
18056 test_258a() {
18057 #define OBD_FAIL_IMUTEX_SEC 0x141c
18058         $LCTL set_param fail_loc=0x141c
18059         touch $DIR/$tfile
18060         chmod u+s $DIR/$tfile
18061         chmod a+rwx $DIR/$tfile
18062         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18063         RC=$?
18064         if [ $RC -ne 0 ]; then
18065                 error "error, failed to take i_mutex, rc=$?"
18066         fi
18067         rm -f $DIR/$tfile
18068 }
18069 run_test 258a "verify i_mutex security behavior when suid attributes is set"
18070
18071 # Verify we do NOT take the i_mutex in the normal case
18072 test_258b() {
18073 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
18074         $LCTL set_param fail_loc=0x141d
18075         touch $DIR/$tfile
18076         chmod a+rwx $DIR
18077         chmod a+rw $DIR/$tfile
18078         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
18079         RC=$?
18080         if [ $RC -ne 0 ]; then
18081                 error "error, took i_mutex unnecessarily, rc=$?"
18082         fi
18083         rm -f $DIR/$tfile
18084
18085 }
18086 run_test 258b "verify i_mutex security behavior"
18087
18088 test_259() {
18089         local file=$DIR/$tfile
18090         local before
18091         local after
18092
18093         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
18094
18095         stack_trap "rm -f $file" EXIT
18096
18097         wait_delete_completed
18098         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18099         echo "before: $before"
18100
18101         $LFS setstripe -i 0 -c 1 $file
18102         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
18103         sync_all_data
18104         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18105         echo "after write: $after"
18106
18107 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
18108         do_facet ost1 $LCTL set_param fail_loc=0x2301
18109         $TRUNCATE $file 0
18110         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18111         echo "after truncate: $after"
18112
18113         stop ost1
18114         do_facet ost1 $LCTL set_param fail_loc=0
18115         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
18116         sleep 2
18117         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
18118         echo "after restart: $after"
18119         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
18120                 error "missing truncate?"
18121
18122         return 0
18123 }
18124 run_test 259 "crash at delayed truncate"
18125
18126 test_260() {
18127 #define OBD_FAIL_MDC_CLOSE               0x806
18128         $LCTL set_param fail_loc=0x80000806
18129         touch $DIR/$tfile
18130
18131 }
18132 run_test 260 "Check mdc_close fail"
18133
18134 ### Data-on-MDT sanity tests ###
18135 test_270a() {
18136         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18137                 skip "Need MDS version at least 2.10.55 for DoM"
18138
18139         # create DoM file
18140         local dom=$DIR/$tdir/dom_file
18141         local tmp=$DIR/$tdir/tmp_file
18142
18143         mkdir -p $DIR/$tdir
18144
18145         # basic checks for DoM component creation
18146         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
18147                 error "Can set MDT layout to non-first entry"
18148
18149         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
18150                 error "Can define multiple entries as MDT layout"
18151
18152         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
18153
18154         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
18155         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
18156         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
18157
18158         local mdtidx=$($LFS getstripe -m $dom)
18159         local mdtname=MDT$(printf %04x $mdtidx)
18160         local facet=mds$((mdtidx + 1))
18161         local space_check=1
18162
18163         # Skip free space checks with ZFS
18164         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
18165
18166         # write
18167         sync
18168         local size_tmp=$((65536 * 3))
18169         local mdtfree1=$(do_facet $facet \
18170                          lctl get_param -n osd*.*$mdtname.kbytesfree)
18171
18172         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18173         # check also direct IO along write
18174         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
18175         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18176         sync
18177         cmp $tmp $dom || error "file data is different"
18178         [ $(stat -c%s $dom) == $size_tmp ] ||
18179                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18180         if [ $space_check == 1 ]; then
18181                 local mdtfree2=$(do_facet $facet \
18182                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
18183
18184                 # increase in usage from by $size_tmp
18185                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18186                         error "MDT free space wrong after write: " \
18187                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18188         fi
18189
18190         # truncate
18191         local size_dom=10000
18192
18193         $TRUNCATE $dom $size_dom
18194         [ $(stat -c%s $dom) == $size_dom ] ||
18195                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18196         if [ $space_check == 1 ]; then
18197                 mdtfree1=$(do_facet $facet \
18198                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18199                 # decrease in usage from $size_tmp to new $size_dom
18200                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18201                   $(((size_tmp - size_dom) / 1024)) ] ||
18202                         error "MDT free space is wrong after truncate: " \
18203                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18204         fi
18205
18206         # append
18207         cat $tmp >> $dom
18208         sync
18209         size_dom=$((size_dom + size_tmp))
18210         [ $(stat -c%s $dom) == $size_dom ] ||
18211                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18212         if [ $space_check == 1 ]; then
18213                 mdtfree2=$(do_facet $facet \
18214                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18215                 # increase in usage by $size_tmp from previous
18216                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18217                         error "MDT free space is wrong after append: " \
18218                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18219         fi
18220
18221         # delete
18222         rm $dom
18223         if [ $space_check == 1 ]; then
18224                 mdtfree1=$(do_facet $facet \
18225                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18226                 # decrease in usage by $size_dom from previous
18227                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18228                         error "MDT free space is wrong after removal: " \
18229                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18230         fi
18231
18232         # combined striping
18233         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18234                 error "Can't create DoM + OST striping"
18235
18236         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18237         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18238         # check also direct IO along write
18239         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18240         sync
18241         cmp $tmp $dom || error "file data is different"
18242         [ $(stat -c%s $dom) == $size_tmp ] ||
18243                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18244         rm $dom $tmp
18245
18246         return 0
18247 }
18248 run_test 270a "DoM: basic functionality tests"
18249
18250 test_270b() {
18251         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18252                 skip "Need MDS version at least 2.10.55"
18253
18254         local dom=$DIR/$tdir/dom_file
18255         local max_size=1048576
18256
18257         mkdir -p $DIR/$tdir
18258         $LFS setstripe -E $max_size -L mdt $dom
18259
18260         # truncate over the limit
18261         $TRUNCATE $dom $(($max_size + 1)) &&
18262                 error "successful truncate over the maximum size"
18263         # write over the limit
18264         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18265                 error "successful write over the maximum size"
18266         # append over the limit
18267         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18268         echo "12345" >> $dom && error "successful append over the maximum size"
18269         rm $dom
18270
18271         return 0
18272 }
18273 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18274
18275 test_270c() {
18276         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18277                 skip "Need MDS version at least 2.10.55"
18278
18279         mkdir -p $DIR/$tdir
18280         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18281
18282         # check files inherit DoM EA
18283         touch $DIR/$tdir/first
18284         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18285                 error "bad pattern"
18286         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18287                 error "bad stripe count"
18288         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18289                 error "bad stripe size"
18290
18291         # check directory inherits DoM EA and uses it as default
18292         mkdir $DIR/$tdir/subdir
18293         touch $DIR/$tdir/subdir/second
18294         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18295                 error "bad pattern in sub-directory"
18296         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18297                 error "bad stripe count in sub-directory"
18298         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18299                 error "bad stripe size in sub-directory"
18300         return 0
18301 }
18302 run_test 270c "DoM: DoM EA inheritance tests"
18303
18304 test_270d() {
18305         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18306                 skip "Need MDS version at least 2.10.55"
18307
18308         mkdir -p $DIR/$tdir
18309         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18310
18311         # inherit default DoM striping
18312         mkdir $DIR/$tdir/subdir
18313         touch $DIR/$tdir/subdir/f1
18314
18315         # change default directory striping
18316         $LFS setstripe -c 1 $DIR/$tdir/subdir
18317         touch $DIR/$tdir/subdir/f2
18318         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18319                 error "wrong default striping in file 2"
18320         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18321                 error "bad pattern in file 2"
18322         return 0
18323 }
18324 run_test 270d "DoM: change striping from DoM to RAID0"
18325
18326 test_270e() {
18327         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18328                 skip "Need MDS version at least 2.10.55"
18329
18330         mkdir -p $DIR/$tdir/dom
18331         mkdir -p $DIR/$tdir/norm
18332         DOMFILES=20
18333         NORMFILES=10
18334         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18335         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18336
18337         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18338         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18339
18340         # find DoM files by layout
18341         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18342         [ $NUM -eq  $DOMFILES ] ||
18343                 error "lfs find -L: found $NUM, expected $DOMFILES"
18344         echo "Test 1: lfs find 20 DOM files by layout: OK"
18345
18346         # there should be 1 dir with default DOM striping
18347         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18348         [ $NUM -eq  1 ] ||
18349                 error "lfs find -L: found $NUM, expected 1 dir"
18350         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18351
18352         # find DoM files by stripe size
18353         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18354         [ $NUM -eq  $DOMFILES ] ||
18355                 error "lfs find -S: found $NUM, expected $DOMFILES"
18356         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18357
18358         # find files by stripe offset except DoM files
18359         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18360         [ $NUM -eq  $NORMFILES ] ||
18361                 error "lfs find -i: found $NUM, expected $NORMFILES"
18362         echo "Test 5: lfs find no DOM files by stripe index: OK"
18363         return 0
18364 }
18365 run_test 270e "DoM: lfs find with DoM files test"
18366
18367 test_270f() {
18368         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18369                 skip "Need MDS version at least 2.10.55"
18370
18371         local mdtname=${FSNAME}-MDT0000-mdtlov
18372         local dom=$DIR/$tdir/dom_file
18373         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18374                                                 lod.$mdtname.dom_stripesize)
18375         local dom_limit=131072
18376
18377         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18378         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18379                                                 lod.$mdtname.dom_stripesize)
18380         [ ${dom_limit} -eq ${dom_current} ] ||
18381                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18382
18383         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18384         $LFS setstripe -d $DIR/$tdir
18385         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18386                 error "Can't set directory default striping"
18387
18388         # exceed maximum stripe size
18389         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18390                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18391         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18392                 error "Able to create DoM component size more than LOD limit"
18393
18394         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18395         dom_current=$(do_facet mds1 $LCTL get_param -n \
18396                                                 lod.$mdtname.dom_stripesize)
18397         [ 0 -eq ${dom_current} ] ||
18398                 error "Can't set zero DoM stripe limit"
18399         rm $dom
18400
18401         # attempt to create DoM file on server with disabled DoM should
18402         # remove DoM entry from layout and be succeed
18403         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18404                 error "Can't create DoM file (DoM is disabled)"
18405         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18406                 error "File has DoM component while DoM is disabled"
18407         rm $dom
18408
18409         # attempt to create DoM file with only DoM stripe should return error
18410         $LFS setstripe -E $dom_limit -L mdt $dom &&
18411                 error "Able to create DoM-only file while DoM is disabled"
18412
18413         # too low values to be aligned with smallest stripe size 64K
18414         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18415         dom_current=$(do_facet mds1 $LCTL get_param -n \
18416                                                 lod.$mdtname.dom_stripesize)
18417         [ 30000 -eq ${dom_current} ] &&
18418                 error "Can set too small DoM stripe limit"
18419
18420         # 64K is a minimal stripe size in Lustre, expect limit of that size
18421         [ 65536 -eq ${dom_current} ] ||
18422                 error "Limit is not set to 64K but ${dom_current}"
18423
18424         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18425         dom_current=$(do_facet mds1 $LCTL get_param -n \
18426                                                 lod.$mdtname.dom_stripesize)
18427         echo $dom_current
18428         [ 2147483648 -eq ${dom_current} ] &&
18429                 error "Can set too large DoM stripe limit"
18430
18431         do_facet mds1 $LCTL set_param -n \
18432                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18433         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18434                 error "Can't create DoM component size after limit change"
18435         do_facet mds1 $LCTL set_param -n \
18436                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18437         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18438                 error "Can't create DoM file after limit decrease"
18439         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18440                 error "Can create big DoM component after limit decrease"
18441         touch ${dom}_def ||
18442                 error "Can't create file with old default layout"
18443
18444         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18445         return 0
18446 }
18447 run_test 270f "DoM: maximum DoM stripe size checks"
18448
18449 test_271a() {
18450         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18451                 skip "Need MDS version at least 2.10.55"
18452
18453         local dom=$DIR/$tdir/dom
18454
18455         mkdir -p $DIR/$tdir
18456
18457         $LFS setstripe -E 1024K -L mdt $dom
18458
18459         lctl set_param -n mdc.*.stats=clear
18460         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18461         cat $dom > /dev/null
18462         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18463         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18464         ls $dom
18465         rm -f $dom
18466 }
18467 run_test 271a "DoM: data is cached for read after write"
18468
18469 test_271b() {
18470         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18471                 skip "Need MDS version at least 2.10.55"
18472
18473         local dom=$DIR/$tdir/dom
18474
18475         mkdir -p $DIR/$tdir
18476
18477         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18478
18479         lctl set_param -n mdc.*.stats=clear
18480         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18481         cancel_lru_locks mdc
18482         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18483         # second stat to check size is cached on client
18484         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18485         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18486         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18487         rm -f $dom
18488 }
18489 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18490
18491 test_271ba() {
18492         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18493                 skip "Need MDS version at least 2.10.55"
18494
18495         local dom=$DIR/$tdir/dom
18496
18497         mkdir -p $DIR/$tdir
18498
18499         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18500
18501         lctl set_param -n mdc.*.stats=clear
18502         lctl set_param -n osc.*.stats=clear
18503         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18504         cancel_lru_locks mdc
18505         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18506         # second stat to check size is cached on client
18507         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18508         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18509         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18510         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18511         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18512         rm -f $dom
18513 }
18514 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18515
18516
18517 get_mdc_stats() {
18518         local mdtidx=$1
18519         local param=$2
18520         local mdt=MDT$(printf %04x $mdtidx)
18521
18522         if [ -z $param ]; then
18523                 lctl get_param -n mdc.*$mdt*.stats
18524         else
18525                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18526         fi
18527 }
18528
18529 test_271c() {
18530         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18531                 skip "Need MDS version at least 2.10.55"
18532
18533         local dom=$DIR/$tdir/dom
18534
18535         mkdir -p $DIR/$tdir
18536
18537         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18538
18539         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18540         local facet=mds$((mdtidx + 1))
18541
18542         cancel_lru_locks mdc
18543         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18544         createmany -o $dom 1000
18545         lctl set_param -n mdc.*.stats=clear
18546         smalliomany -w $dom 1000 200
18547         get_mdc_stats $mdtidx
18548         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18549         # Each file has 1 open, 1 IO enqueues, total 2000
18550         # but now we have also +1 getxattr for security.capability, total 3000
18551         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18552         unlinkmany $dom 1000
18553
18554         cancel_lru_locks mdc
18555         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18556         createmany -o $dom 1000
18557         lctl set_param -n mdc.*.stats=clear
18558         smalliomany -w $dom 1000 200
18559         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18560         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18561         # for OPEN and IO lock.
18562         [ $((enq - enq_2)) -ge 1000 ] ||
18563                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18564         unlinkmany $dom 1000
18565         return 0
18566 }
18567 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18568
18569 cleanup_271def_tests() {
18570         trap 0
18571         rm -f $1
18572 }
18573
18574 test_271d() {
18575         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18576                 skip "Need MDS version at least 2.10.57"
18577
18578         local dom=$DIR/$tdir/dom
18579         local tmp=$TMP/$tfile
18580         trap "cleanup_271def_tests $tmp" EXIT
18581
18582         mkdir -p $DIR/$tdir
18583
18584         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18585
18586         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18587
18588         cancel_lru_locks mdc
18589         dd if=/dev/urandom of=$tmp bs=1000 count=1
18590         dd if=$tmp of=$dom bs=1000 count=1
18591         cancel_lru_locks mdc
18592
18593         cat /etc/hosts >> $tmp
18594         lctl set_param -n mdc.*.stats=clear
18595
18596         # append data to the same file it should update local page
18597         echo "Append to the same page"
18598         cat /etc/hosts >> $dom
18599         local num=$(get_mdc_stats $mdtidx ost_read)
18600         local ra=$(get_mdc_stats $mdtidx req_active)
18601         local rw=$(get_mdc_stats $mdtidx req_waittime)
18602
18603         [ -z $num ] || error "$num READ RPC occured"
18604         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18605         echo "... DONE"
18606
18607         # compare content
18608         cmp $tmp $dom || error "file miscompare"
18609
18610         cancel_lru_locks mdc
18611         lctl set_param -n mdc.*.stats=clear
18612
18613         echo "Open and read file"
18614         cat $dom > /dev/null
18615         local num=$(get_mdc_stats $mdtidx ost_read)
18616         local ra=$(get_mdc_stats $mdtidx req_active)
18617         local rw=$(get_mdc_stats $mdtidx req_waittime)
18618
18619         [ -z $num ] || error "$num READ RPC occured"
18620         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18621         echo "... DONE"
18622
18623         # compare content
18624         cmp $tmp $dom || error "file miscompare"
18625
18626         return 0
18627 }
18628 run_test 271d "DoM: read on open (1K file in reply buffer)"
18629
18630 test_271f() {
18631         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18632                 skip "Need MDS version at least 2.10.57"
18633
18634         local dom=$DIR/$tdir/dom
18635         local tmp=$TMP/$tfile
18636         trap "cleanup_271def_tests $tmp" EXIT
18637
18638         mkdir -p $DIR/$tdir
18639
18640         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18641
18642         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18643
18644         cancel_lru_locks mdc
18645         dd if=/dev/urandom of=$tmp bs=265000 count=1
18646         dd if=$tmp of=$dom bs=265000 count=1
18647         cancel_lru_locks mdc
18648         cat /etc/hosts >> $tmp
18649         lctl set_param -n mdc.*.stats=clear
18650
18651         echo "Append to the same page"
18652         cat /etc/hosts >> $dom
18653         local num=$(get_mdc_stats $mdtidx ost_read)
18654         local ra=$(get_mdc_stats $mdtidx req_active)
18655         local rw=$(get_mdc_stats $mdtidx req_waittime)
18656
18657         [ -z $num ] || error "$num READ RPC occured"
18658         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18659         echo "... DONE"
18660
18661         # compare content
18662         cmp $tmp $dom || error "file miscompare"
18663
18664         cancel_lru_locks mdc
18665         lctl set_param -n mdc.*.stats=clear
18666
18667         echo "Open and read file"
18668         cat $dom > /dev/null
18669         local num=$(get_mdc_stats $mdtidx ost_read)
18670         local ra=$(get_mdc_stats $mdtidx req_active)
18671         local rw=$(get_mdc_stats $mdtidx req_waittime)
18672
18673         [ -z $num ] && num=0
18674         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18675         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18676         echo "... DONE"
18677
18678         # compare content
18679         cmp $tmp $dom || error "file miscompare"
18680
18681         return 0
18682 }
18683 run_test 271f "DoM: read on open (200K file and read tail)"
18684
18685 test_271g() {
18686         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18687                 skip "Skipping due to old client or server version"
18688
18689         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18690         # to get layout
18691         $CHECKSTAT -t file $DIR1/$tfile
18692
18693         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18694         MULTIOP_PID=$!
18695         sleep 1
18696         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18697         $LCTL set_param fail_loc=0x80000314
18698         rm $DIR1/$tfile || error "Unlink fails"
18699         RC=$?
18700         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18701         [ $RC -eq 0 ] || error "Failed write to stale object"
18702 }
18703 run_test 271g "Discard DoM data vs client flush race"
18704
18705 test_272a() {
18706         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18707                 skip "Need MDS version at least 2.11.50"
18708
18709         local dom=$DIR/$tdir/dom
18710         mkdir -p $DIR/$tdir
18711
18712         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18713         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18714                 error "failed to write data into $dom"
18715         local old_md5=$(md5sum $dom)
18716
18717         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18718                 error "failed to migrate to the same DoM component"
18719
18720         local new_md5=$(md5sum $dom)
18721
18722         [ "$old_md5" == "$new_md5" ] ||
18723                 error "md5sum differ: $old_md5, $new_md5"
18724
18725         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18726                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18727 }
18728 run_test 272a "DoM migration: new layout with the same DOM component"
18729
18730 test_272b() {
18731         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18732                 skip "Need MDS version at least 2.11.50"
18733
18734         local dom=$DIR/$tdir/dom
18735         mkdir -p $DIR/$tdir
18736         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18737
18738         local mdtidx=$($LFS getstripe -m $dom)
18739         local mdtname=MDT$(printf %04x $mdtidx)
18740         local facet=mds$((mdtidx + 1))
18741
18742         local mdtfree1=$(do_facet $facet \
18743                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18744         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18745                 error "failed to write data into $dom"
18746         local old_md5=$(md5sum $dom)
18747         cancel_lru_locks mdc
18748         local mdtfree1=$(do_facet $facet \
18749                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18750
18751         $LFS migrate -c2 $dom ||
18752                 error "failed to migrate to the new composite layout"
18753         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18754                 error "MDT stripe was not removed"
18755
18756         cancel_lru_locks mdc
18757         local new_md5=$(md5sum $dom)
18758         [ "$old_md5" == "$new_md5" ] ||
18759                 error "$old_md5 != $new_md5"
18760
18761         # Skip free space checks with ZFS
18762         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18763                 local mdtfree2=$(do_facet $facet \
18764                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18765                 [ $mdtfree2 -gt $mdtfree1 ] ||
18766                         error "MDT space is not freed after migration"
18767         fi
18768         return 0
18769 }
18770 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18771
18772 test_272c() {
18773         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18774                 skip "Need MDS version at least 2.11.50"
18775
18776         local dom=$DIR/$tdir/$tfile
18777         mkdir -p $DIR/$tdir
18778         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18779
18780         local mdtidx=$($LFS getstripe -m $dom)
18781         local mdtname=MDT$(printf %04x $mdtidx)
18782         local facet=mds$((mdtidx + 1))
18783
18784         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18785                 error "failed to write data into $dom"
18786         local old_md5=$(md5sum $dom)
18787         cancel_lru_locks mdc
18788         local mdtfree1=$(do_facet $facet \
18789                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18790
18791         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18792                 error "failed to migrate to the new composite layout"
18793         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18794                 error "MDT stripe was not removed"
18795
18796         cancel_lru_locks mdc
18797         local new_md5=$(md5sum $dom)
18798         [ "$old_md5" == "$new_md5" ] ||
18799                 error "$old_md5 != $new_md5"
18800
18801         # Skip free space checks with ZFS
18802         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18803                 local mdtfree2=$(do_facet $facet \
18804                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18805                 [ $mdtfree2 -gt $mdtfree1 ] ||
18806                         error "MDS space is not freed after migration"
18807         fi
18808         return 0
18809 }
18810 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18811
18812 test_272d() {
18813         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18814                 skip "Need MDS version at least 2.12.55"
18815
18816         local dom=$DIR/$tdir/$tfile
18817         mkdir -p $DIR/$tdir
18818         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18819
18820         local mdtidx=$($LFS getstripe -m $dom)
18821         local mdtname=MDT$(printf %04x $mdtidx)
18822         local facet=mds$((mdtidx + 1))
18823
18824         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18825                 error "failed to write data into $dom"
18826         local old_md5=$(md5sum $dom)
18827         cancel_lru_locks mdc
18828         local mdtfree1=$(do_facet $facet \
18829                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18830
18831         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
18832                 error "failed mirroring to the new composite layout"
18833         $LFS mirror resync $dom ||
18834                 error "failed mirror resync"
18835         $LFS mirror split --mirror-id 1 -d $dom ||
18836                 error "failed mirror split"
18837
18838         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18839                 error "MDT stripe was not removed"
18840
18841         cancel_lru_locks mdc
18842         local new_md5=$(md5sum $dom)
18843         [ "$old_md5" == "$new_md5" ] ||
18844                 error "$old_md5 != $new_md5"
18845
18846         # Skip free space checks with ZFS
18847         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18848                 local mdtfree2=$(do_facet $facet \
18849                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18850                 [ $mdtfree2 -gt $mdtfree1 ] ||
18851                         error "MDS space is not freed after DOM mirror deletion"
18852         fi
18853         return 0
18854 }
18855 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
18856
18857 test_272e() {
18858         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18859                 skip "Need MDS version at least 2.12.55"
18860
18861         local dom=$DIR/$tdir/$tfile
18862         mkdir -p $DIR/$tdir
18863         $LFS setstripe -c 2 $dom
18864
18865         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18866                 error "failed to write data into $dom"
18867         local old_md5=$(md5sum $dom)
18868         cancel_lru_locks mdc
18869
18870         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
18871                 error "failed mirroring to the DOM layout"
18872         $LFS mirror resync $dom ||
18873                 error "failed mirror resync"
18874         $LFS mirror split --mirror-id 1 -d $dom ||
18875                 error "failed mirror split"
18876
18877         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18878                 error "MDT stripe was not removed"
18879
18880         cancel_lru_locks mdc
18881         local new_md5=$(md5sum $dom)
18882         [ "$old_md5" == "$new_md5" ] ||
18883                 error "$old_md5 != $new_md5"
18884
18885         return 0
18886 }
18887 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
18888
18889 test_272f() {
18890         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18891                 skip "Need MDS version at least 2.12.55"
18892
18893         local dom=$DIR/$tdir/$tfile
18894         mkdir -p $DIR/$tdir
18895         $LFS setstripe -c 2 $dom
18896
18897         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18898                 error "failed to write data into $dom"
18899         local old_md5=$(md5sum $dom)
18900         cancel_lru_locks mdc
18901
18902         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
18903                 error "failed migrating to the DOM file"
18904
18905         cancel_lru_locks mdc
18906         local new_md5=$(md5sum $dom)
18907         [ "$old_md5" != "$new_md5" ] &&
18908                 error "$old_md5 != $new_md5"
18909
18910         return 0
18911 }
18912 run_test 272f "DoM migration: OST-striped file to DOM file"
18913
18914 test_273a() {
18915         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18916                 skip "Need MDS version at least 2.11.50"
18917
18918         # Layout swap cannot be done if either file has DOM component,
18919         # this will never be supported, migration should be used instead
18920
18921         local dom=$DIR/$tdir/$tfile
18922         mkdir -p $DIR/$tdir
18923
18924         $LFS setstripe -c2 ${dom}_plain
18925         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18926         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18927                 error "can swap layout with DoM component"
18928         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18929                 error "can swap layout with DoM component"
18930
18931         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18932         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18933                 error "can swap layout with DoM component"
18934         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18935                 error "can swap layout with DoM component"
18936         return 0
18937 }
18938 run_test 273a "DoM: layout swapping should fail with DOM"
18939
18940 test_275() {
18941         remote_ost_nodsh && skip "remote OST with nodsh"
18942         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18943                 skip "Need OST version >= 2.10.57"
18944
18945         local file=$DIR/$tfile
18946         local oss
18947
18948         oss=$(comma_list $(osts_nodes))
18949
18950         dd if=/dev/urandom of=$file bs=1M count=2 ||
18951                 error "failed to create a file"
18952         cancel_lru_locks osc
18953
18954         #lock 1
18955         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18956                 error "failed to read a file"
18957
18958 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18959         $LCTL set_param fail_loc=0x8000031f
18960
18961         cancel_lru_locks osc &
18962         sleep 1
18963
18964 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18965         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18966         #IO takes another lock, but matches the PENDING one
18967         #and places it to the IO RPC
18968         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18969                 error "failed to read a file with PENDING lock"
18970 }
18971 run_test 275 "Read on a canceled duplicate lock"
18972
18973 test_276() {
18974         remote_ost_nodsh && skip "remote OST with nodsh"
18975         local pid
18976
18977         do_facet ost1 "(while true; do \
18978                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18979                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18980         pid=$!
18981
18982         for LOOP in $(seq 20); do
18983                 stop ost1
18984                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18985         done
18986         kill -9 $pid
18987         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18988                 rm $TMP/sanity_276_pid"
18989 }
18990 run_test 276 "Race between mount and obd_statfs"
18991
18992 test_277() {
18993         $LCTL set_param ldlm.namespaces.*.lru_size=0
18994         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
18995         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18996                         grep ^used_mb | awk '{print $2}')
18997         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
18998         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
18999                 oflag=direct conv=notrunc
19000         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
19001                         grep ^used_mb | awk '{print $2}')
19002         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
19003 }
19004 run_test 277 "Direct IO shall drop page cache"
19005
19006 test_278() {
19007         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
19008         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19009         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
19010                 skip "needs the same host for mdt1 mdt2" && return
19011
19012         local pid1
19013         local pid2
19014
19015 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
19016         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
19017         stop mds2 &
19018         pid2=$!
19019
19020         stop mds1
19021
19022         echo "Starting MDTs"
19023         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
19024         wait $pid2
19025 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
19026 #will return NULL
19027         do_facet mds2 $LCTL set_param fail_loc=0
19028
19029         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
19030         wait_recovery_complete mds2
19031 }
19032 run_test 278 "Race starting MDS between MDTs stop/start"
19033
19034 cleanup_test_300() {
19035         trap 0
19036         umask $SAVE_UMASK
19037 }
19038 test_striped_dir() {
19039         local mdt_index=$1
19040         local stripe_count
19041         local stripe_index
19042
19043         mkdir -p $DIR/$tdir
19044
19045         SAVE_UMASK=$(umask)
19046         trap cleanup_test_300 RETURN EXIT
19047
19048         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
19049                                                 $DIR/$tdir/striped_dir ||
19050                 error "set striped dir error"
19051
19052         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
19053         [ "$mode" = "755" ] || error "expect 755 got $mode"
19054
19055         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
19056                 error "getdirstripe failed"
19057         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
19058         if [ "$stripe_count" != "2" ]; then
19059                 error "1:stripe_count is $stripe_count, expect 2"
19060         fi
19061         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
19062         if [ "$stripe_count" != "2" ]; then
19063                 error "2:stripe_count is $stripe_count, expect 2"
19064         fi
19065
19066         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
19067         if [ "$stripe_index" != "$mdt_index" ]; then
19068                 error "stripe_index is $stripe_index, expect $mdt_index"
19069         fi
19070
19071         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19072                 error "nlink error after create striped dir"
19073
19074         mkdir $DIR/$tdir/striped_dir/a
19075         mkdir $DIR/$tdir/striped_dir/b
19076
19077         stat $DIR/$tdir/striped_dir/a ||
19078                 error "create dir under striped dir failed"
19079         stat $DIR/$tdir/striped_dir/b ||
19080                 error "create dir under striped dir failed"
19081
19082         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
19083                 error "nlink error after mkdir"
19084
19085         rmdir $DIR/$tdir/striped_dir/a
19086         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
19087                 error "nlink error after rmdir"
19088
19089         rmdir $DIR/$tdir/striped_dir/b
19090         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
19091                 error "nlink error after rmdir"
19092
19093         chattr +i $DIR/$tdir/striped_dir
19094         createmany -o $DIR/$tdir/striped_dir/f 10 &&
19095                 error "immutable flags not working under striped dir!"
19096         chattr -i $DIR/$tdir/striped_dir
19097
19098         rmdir $DIR/$tdir/striped_dir ||
19099                 error "rmdir striped dir error"
19100
19101         cleanup_test_300
19102
19103         true
19104 }
19105
19106 test_300a() {
19107         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19108                 skip "skipped for lustre < 2.7.0"
19109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19110         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19111
19112         test_striped_dir 0 || error "failed on striped dir on MDT0"
19113         test_striped_dir 1 || error "failed on striped dir on MDT0"
19114 }
19115 run_test 300a "basic striped dir sanity test"
19116
19117 test_300b() {
19118         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19119                 skip "skipped for lustre < 2.7.0"
19120         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19121         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19122
19123         local i
19124         local mtime1
19125         local mtime2
19126         local mtime3
19127
19128         test_mkdir $DIR/$tdir || error "mkdir fail"
19129         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19130                 error "set striped dir error"
19131         for i in {0..9}; do
19132                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
19133                 sleep 1
19134                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
19135                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
19136                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
19137                 sleep 1
19138                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
19139                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
19140                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
19141         done
19142         true
19143 }
19144 run_test 300b "check ctime/mtime for striped dir"
19145
19146 test_300c() {
19147         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19148                 skip "skipped for lustre < 2.7.0"
19149         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19150         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19151
19152         local file_count
19153
19154         mkdir -p $DIR/$tdir
19155         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
19156                 error "set striped dir error"
19157
19158         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
19159                 error "chown striped dir failed"
19160
19161         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
19162                 error "create 5k files failed"
19163
19164         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
19165
19166         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
19167
19168         rm -rf $DIR/$tdir
19169 }
19170 run_test 300c "chown && check ls under striped directory"
19171
19172 test_300d() {
19173         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
19174                 skip "skipped for lustre < 2.7.0"
19175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19176         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19177
19178         local stripe_count
19179         local file
19180
19181         mkdir -p $DIR/$tdir
19182         $LFS setstripe -c 2 $DIR/$tdir
19183
19184         #local striped directory
19185         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19186                 error "set striped dir error"
19187         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19188                 error "create 10 files failed"
19189
19190         #remote striped directory
19191         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19192                 error "set striped dir error"
19193         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19194                 error "create 10 files failed"
19195
19196         for file in $(find $DIR/$tdir); do
19197                 stripe_count=$($LFS getstripe -c $file)
19198                 [ $stripe_count -eq 2 ] ||
19199                         error "wrong stripe $stripe_count for $file"
19200         done
19201
19202         rm -rf $DIR/$tdir
19203 }
19204 run_test 300d "check default stripe under striped directory"
19205
19206 test_300e() {
19207         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19208                 skip "Need MDS version at least 2.7.55"
19209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19210         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19211
19212         local stripe_count
19213         local file
19214
19215         mkdir -p $DIR/$tdir
19216
19217         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19218                 error "set striped dir error"
19219
19220         touch $DIR/$tdir/striped_dir/a
19221         touch $DIR/$tdir/striped_dir/b
19222         touch $DIR/$tdir/striped_dir/c
19223
19224         mkdir $DIR/$tdir/striped_dir/dir_a
19225         mkdir $DIR/$tdir/striped_dir/dir_b
19226         mkdir $DIR/$tdir/striped_dir/dir_c
19227
19228         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19229                 error "set striped adir under striped dir error"
19230
19231         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19232                 error "set striped bdir under striped dir error"
19233
19234         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19235                 error "set striped cdir under striped dir error"
19236
19237         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19238                 error "rename dir under striped dir fails"
19239
19240         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19241                 error "rename dir under different stripes fails"
19242
19243         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19244                 error "rename file under striped dir should succeed"
19245
19246         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19247                 error "rename dir under striped dir should succeed"
19248
19249         rm -rf $DIR/$tdir
19250 }
19251 run_test 300e "check rename under striped directory"
19252
19253 test_300f() {
19254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19255         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19256         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19257                 skip "Need MDS version at least 2.7.55"
19258
19259         local stripe_count
19260         local file
19261
19262         rm -rf $DIR/$tdir
19263         mkdir -p $DIR/$tdir
19264
19265         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19266                 error "set striped dir error"
19267
19268         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19269                 error "set striped dir error"
19270
19271         touch $DIR/$tdir/striped_dir/a
19272         mkdir $DIR/$tdir/striped_dir/dir_a
19273         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19274                 error "create striped dir under striped dir fails"
19275
19276         touch $DIR/$tdir/striped_dir1/b
19277         mkdir $DIR/$tdir/striped_dir1/dir_b
19278         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19279                 error "create striped dir under striped dir fails"
19280
19281         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19282                 error "rename dir under different striped dir should fail"
19283
19284         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19285                 error "rename striped dir under diff striped dir should fail"
19286
19287         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19288                 error "rename file under diff striped dirs fails"
19289
19290         rm -rf $DIR/$tdir
19291 }
19292 run_test 300f "check rename cross striped directory"
19293
19294 test_300_check_default_striped_dir()
19295 {
19296         local dirname=$1
19297         local default_count=$2
19298         local default_index=$3
19299         local stripe_count
19300         local stripe_index
19301         local dir_stripe_index
19302         local dir
19303
19304         echo "checking $dirname $default_count $default_index"
19305         $LFS setdirstripe -D -c $default_count -i $default_index \
19306                                 -t all_char $DIR/$tdir/$dirname ||
19307                 error "set default stripe on striped dir error"
19308         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19309         [ $stripe_count -eq $default_count ] ||
19310                 error "expect $default_count get $stripe_count for $dirname"
19311
19312         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19313         [ $stripe_index -eq $default_index ] ||
19314                 error "expect $default_index get $stripe_index for $dirname"
19315
19316         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19317                                                 error "create dirs failed"
19318
19319         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19320         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19321         for dir in $(find $DIR/$tdir/$dirname/*); do
19322                 stripe_count=$($LFS getdirstripe -c $dir)
19323                 [ $stripe_count -eq $default_count ] ||
19324                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19325                 error "stripe count $default_count != $stripe_count for $dir"
19326
19327                 stripe_index=$($LFS getdirstripe -i $dir)
19328                 [ $default_index -eq -1 ] ||
19329                         [ $stripe_index -eq $default_index ] ||
19330                         error "$stripe_index != $default_index for $dir"
19331
19332                 #check default stripe
19333                 stripe_count=$($LFS getdirstripe -D -c $dir)
19334                 [ $stripe_count -eq $default_count ] ||
19335                 error "default count $default_count != $stripe_count for $dir"
19336
19337                 stripe_index=$($LFS getdirstripe -D -i $dir)
19338                 [ $stripe_index -eq $default_index ] ||
19339                 error "default index $default_index != $stripe_index for $dir"
19340         done
19341         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19342 }
19343
19344 test_300g() {
19345         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19346         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19347                 skip "Need MDS version at least 2.7.55"
19348
19349         local dir
19350         local stripe_count
19351         local stripe_index
19352
19353         mkdir $DIR/$tdir
19354         mkdir $DIR/$tdir/normal_dir
19355
19356         #Checking when client cache stripe index
19357         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19358         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19359                 error "create striped_dir failed"
19360
19361         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19362                 error "create dir0 fails"
19363         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19364         [ $stripe_index -eq 0 ] ||
19365                 error "dir0 expect index 0 got $stripe_index"
19366
19367         mkdir $DIR/$tdir/striped_dir/dir1 ||
19368                 error "create dir1 fails"
19369         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19370         [ $stripe_index -eq 1 ] ||
19371                 error "dir1 expect index 1 got $stripe_index"
19372
19373         #check default stripe count/stripe index
19374         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19375         test_300_check_default_striped_dir normal_dir 1 0
19376         test_300_check_default_striped_dir normal_dir 2 1
19377         test_300_check_default_striped_dir normal_dir 2 -1
19378
19379         #delete default stripe information
19380         echo "delete default stripeEA"
19381         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19382                 error "set default stripe on striped dir error"
19383
19384         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19385         for dir in $(find $DIR/$tdir/normal_dir/*); do
19386                 stripe_count=$($LFS getdirstripe -c $dir)
19387                 [ $stripe_count -eq 0 ] ||
19388                         error "expect 1 get $stripe_count for $dir"
19389                 stripe_index=$($LFS getdirstripe -i $dir)
19390                 [ $stripe_index -eq 0 ] ||
19391                         error "expect 0 get $stripe_index for $dir"
19392         done
19393 }
19394 run_test 300g "check default striped directory for normal directory"
19395
19396 test_300h() {
19397         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19398         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19399                 skip "Need MDS version at least 2.7.55"
19400
19401         local dir
19402         local stripe_count
19403
19404         mkdir $DIR/$tdir
19405         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19406                 error "set striped dir error"
19407
19408         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19409         test_300_check_default_striped_dir striped_dir 1 0
19410         test_300_check_default_striped_dir striped_dir 2 1
19411         test_300_check_default_striped_dir striped_dir 2 -1
19412
19413         #delete default stripe information
19414         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19415                 error "set default stripe on striped dir error"
19416
19417         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19418         for dir in $(find $DIR/$tdir/striped_dir/*); do
19419                 stripe_count=$($LFS getdirstripe -c $dir)
19420                 [ $stripe_count -eq 0 ] ||
19421                         error "expect 1 get $stripe_count for $dir"
19422         done
19423 }
19424 run_test 300h "check default striped directory for striped directory"
19425
19426 test_300i() {
19427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19428         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19429         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19430                 skip "Need MDS version at least 2.7.55"
19431
19432         local stripe_count
19433         local file
19434
19435         mkdir $DIR/$tdir
19436
19437         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19438                 error "set striped dir error"
19439
19440         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19441                 error "create files under striped dir failed"
19442
19443         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19444                 error "set striped hashdir error"
19445
19446         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19447                 error "create dir0 under hash dir failed"
19448         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19449                 error "create dir1 under hash dir failed"
19450
19451         # unfortunately, we need to umount to clear dir layout cache for now
19452         # once we fully implement dir layout, we can drop this
19453         umount_client $MOUNT || error "umount failed"
19454         mount_client $MOUNT || error "mount failed"
19455
19456         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19457         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19458         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19459
19460         #set the stripe to be unknown hash type
19461         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19462         $LCTL set_param fail_loc=0x1901
19463         for ((i = 0; i < 10; i++)); do
19464                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19465                         error "stat f-$i failed"
19466                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19467         done
19468
19469         touch $DIR/$tdir/striped_dir/f0 &&
19470                 error "create under striped dir with unknown hash should fail"
19471
19472         $LCTL set_param fail_loc=0
19473
19474         umount_client $MOUNT || error "umount failed"
19475         mount_client $MOUNT || error "mount failed"
19476
19477         return 0
19478 }
19479 run_test 300i "client handle unknown hash type striped directory"
19480
19481 test_300j() {
19482         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19484         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19485                 skip "Need MDS version at least 2.7.55"
19486
19487         local stripe_count
19488         local file
19489
19490         mkdir $DIR/$tdir
19491
19492         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19493         $LCTL set_param fail_loc=0x1702
19494         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19495                 error "set striped dir error"
19496
19497         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19498                 error "create files under striped dir failed"
19499
19500         $LCTL set_param fail_loc=0
19501
19502         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19503
19504         return 0
19505 }
19506 run_test 300j "test large update record"
19507
19508 test_300k() {
19509         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19510         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19511         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19512                 skip "Need MDS version at least 2.7.55"
19513
19514         # this test needs a huge transaction
19515         local kb
19516         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19517         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19518
19519         local stripe_count
19520         local file
19521
19522         mkdir $DIR/$tdir
19523
19524         #define OBD_FAIL_LARGE_STRIPE   0x1703
19525         $LCTL set_param fail_loc=0x1703
19526         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19527                 error "set striped dir error"
19528         $LCTL set_param fail_loc=0
19529
19530         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19531                 error "getstripeddir fails"
19532         rm -rf $DIR/$tdir/striped_dir ||
19533                 error "unlink striped dir fails"
19534
19535         return 0
19536 }
19537 run_test 300k "test large striped directory"
19538
19539 test_300l() {
19540         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19541         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19542         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19543                 skip "Need MDS version at least 2.7.55"
19544
19545         local stripe_index
19546
19547         test_mkdir -p $DIR/$tdir/striped_dir
19548         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19549                         error "chown $RUNAS_ID failed"
19550         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19551                 error "set default striped dir failed"
19552
19553         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19554         $LCTL set_param fail_loc=0x80000158
19555         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19556
19557         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19558         [ $stripe_index -eq 1 ] ||
19559                 error "expect 1 get $stripe_index for $dir"
19560 }
19561 run_test 300l "non-root user to create dir under striped dir with stale layout"
19562
19563 test_300m() {
19564         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19565         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19566         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19567                 skip "Need MDS version at least 2.7.55"
19568
19569         mkdir -p $DIR/$tdir/striped_dir
19570         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19571                 error "set default stripes dir error"
19572
19573         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19574
19575         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19576         [ $stripe_count -eq 0 ] ||
19577                         error "expect 0 get $stripe_count for a"
19578
19579         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19580                 error "set default stripes dir error"
19581
19582         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19583
19584         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19585         [ $stripe_count -eq 0 ] ||
19586                         error "expect 0 get $stripe_count for b"
19587
19588         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19589                 error "set default stripes dir error"
19590
19591         mkdir $DIR/$tdir/striped_dir/c &&
19592                 error "default stripe_index is invalid, mkdir c should fails"
19593
19594         rm -rf $DIR/$tdir || error "rmdir fails"
19595 }
19596 run_test 300m "setstriped directory on single MDT FS"
19597
19598 cleanup_300n() {
19599         local list=$(comma_list $(mdts_nodes))
19600
19601         trap 0
19602         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19603 }
19604
19605 test_300n() {
19606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19607         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19608         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19609                 skip "Need MDS version at least 2.7.55"
19610         remote_mds_nodsh && skip "remote MDS with nodsh"
19611
19612         local stripe_index
19613         local list=$(comma_list $(mdts_nodes))
19614
19615         trap cleanup_300n RETURN EXIT
19616         mkdir -p $DIR/$tdir
19617         chmod 777 $DIR/$tdir
19618         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19619                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19620                 error "create striped dir succeeds with gid=0"
19621
19622         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19623         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19624                 error "create striped dir fails with gid=-1"
19625
19626         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19627         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19628                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19629                 error "set default striped dir succeeds with gid=0"
19630
19631
19632         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19633         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19634                 error "set default striped dir fails with gid=-1"
19635
19636
19637         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19638         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19639                                         error "create test_dir fails"
19640         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19641                                         error "create test_dir1 fails"
19642         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19643                                         error "create test_dir2 fails"
19644         cleanup_300n
19645 }
19646 run_test 300n "non-root user to create dir under striped dir with default EA"
19647
19648 test_300o() {
19649         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19650         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19651         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19652                 skip "Need MDS version at least 2.7.55"
19653
19654         local numfree1
19655         local numfree2
19656
19657         mkdir -p $DIR/$tdir
19658
19659         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19660         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19661         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19662                 skip "not enough free inodes $numfree1 $numfree2"
19663         fi
19664
19665         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19666         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19667         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19668                 skip "not enough free space $numfree1 $numfree2"
19669         fi
19670
19671         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19672                 error "setdirstripe fails"
19673
19674         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19675                 error "create dirs fails"
19676
19677         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19678         ls $DIR/$tdir/striped_dir > /dev/null ||
19679                 error "ls striped dir fails"
19680         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19681                 error "unlink big striped dir fails"
19682 }
19683 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19684
19685 test_300p() {
19686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19688         remote_mds_nodsh && skip "remote MDS with nodsh"
19689
19690         mkdir -p $DIR/$tdir
19691
19692         #define OBD_FAIL_OUT_ENOSPC     0x1704
19693         do_facet mds2 lctl set_param fail_loc=0x80001704
19694         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19695                  && error "create striped directory should fail"
19696
19697         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19698
19699         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19700         true
19701 }
19702 run_test 300p "create striped directory without space"
19703
19704 test_300q() {
19705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19706         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19707
19708         local fd=$(free_fd)
19709         local cmd="exec $fd<$tdir"
19710         cd $DIR
19711         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19712         eval $cmd
19713         cmd="exec $fd<&-"
19714         trap "eval $cmd" EXIT
19715         cd $tdir || error "cd $tdir fails"
19716         rmdir  ../$tdir || error "rmdir $tdir fails"
19717         mkdir local_dir && error "create dir succeeds"
19718         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19719         eval $cmd
19720         return 0
19721 }
19722 run_test 300q "create remote directory under orphan directory"
19723
19724 test_300r() {
19725         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19726                 skip "Need MDS version at least 2.7.55" && return
19727         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19728
19729         mkdir $DIR/$tdir
19730
19731         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19732                 error "set striped dir error"
19733
19734         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19735                 error "getstripeddir fails"
19736
19737         local stripe_count
19738         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19739                       awk '/lmv_stripe_count:/ { print $2 }')
19740
19741         [ $MDSCOUNT -ne $stripe_count ] &&
19742                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19743
19744         rm -rf $DIR/$tdir/striped_dir ||
19745                 error "unlink striped dir fails"
19746 }
19747 run_test 300r "test -1 striped directory"
19748
19749 prepare_remote_file() {
19750         mkdir $DIR/$tdir/src_dir ||
19751                 error "create remote source failed"
19752
19753         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19754                  error "cp to remote source failed"
19755         touch $DIR/$tdir/src_dir/a
19756
19757         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19758                 error "create remote target dir failed"
19759
19760         touch $DIR/$tdir/tgt_dir/b
19761
19762         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19763                 error "rename dir cross MDT failed!"
19764
19765         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19766                 error "src_child still exists after rename"
19767
19768         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19769                 error "missing file(a) after rename"
19770
19771         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19772                 error "diff after rename"
19773 }
19774
19775 test_310a() {
19776         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19777         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19778
19779         local remote_file=$DIR/$tdir/tgt_dir/b
19780
19781         mkdir -p $DIR/$tdir
19782
19783         prepare_remote_file || error "prepare remote file failed"
19784
19785         #open-unlink file
19786         $OPENUNLINK $remote_file $remote_file ||
19787                 error "openunlink $remote_file failed"
19788         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19789 }
19790 run_test 310a "open unlink remote file"
19791
19792 test_310b() {
19793         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19794         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19795
19796         local remote_file=$DIR/$tdir/tgt_dir/b
19797
19798         mkdir -p $DIR/$tdir
19799
19800         prepare_remote_file || error "prepare remote file failed"
19801
19802         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19803         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19804         $CHECKSTAT -t file $remote_file || error "check file failed"
19805 }
19806 run_test 310b "unlink remote file with multiple links while open"
19807
19808 test_310c() {
19809         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19810         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19811
19812         local remote_file=$DIR/$tdir/tgt_dir/b
19813
19814         mkdir -p $DIR/$tdir
19815
19816         prepare_remote_file || error "prepare remote file failed"
19817
19818         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19819         multiop_bg_pause $remote_file O_uc ||
19820                         error "mulitop failed for remote file"
19821         MULTIPID=$!
19822         $MULTIOP $DIR/$tfile Ouc
19823         kill -USR1 $MULTIPID
19824         wait $MULTIPID
19825 }
19826 run_test 310c "open-unlink remote file with multiple links"
19827
19828 #LU-4825
19829 test_311() {
19830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19831         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19832         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19833                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19834         remote_mds_nodsh && skip "remote MDS with nodsh"
19835
19836         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19837         local mdts=$(comma_list $(mdts_nodes))
19838
19839         mkdir -p $DIR/$tdir
19840         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19841         createmany -o $DIR/$tdir/$tfile. 1000
19842
19843         # statfs data is not real time, let's just calculate it
19844         old_iused=$((old_iused + 1000))
19845
19846         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19847                         osp.*OST0000*MDT0000.create_count")
19848         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19849                                 osp.*OST0000*MDT0000.max_create_count")
19850         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19851
19852         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19853         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19854         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19855
19856         unlinkmany $DIR/$tdir/$tfile. 1000
19857
19858         do_nodes $mdts "$LCTL set_param -n \
19859                         osp.*OST0000*.max_create_count=$max_count"
19860         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19861                 do_nodes $mdts "$LCTL set_param -n \
19862                                 osp.*OST0000*.create_count=$count"
19863         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19864                         grep "=0" && error "create_count is zero"
19865
19866         local new_iused
19867         for i in $(seq 120); do
19868                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19869                 # system may be too busy to destroy all objs in time, use
19870                 # a somewhat small value to not fail autotest
19871                 [ $((old_iused - new_iused)) -gt 400 ] && break
19872                 sleep 1
19873         done
19874
19875         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19876         [ $((old_iused - new_iused)) -gt 400 ] ||
19877                 error "objs not destroyed after unlink"
19878 }
19879 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19880
19881 zfs_oid_to_objid()
19882 {
19883         local ost=$1
19884         local objid=$2
19885
19886         local vdevdir=$(dirname $(facet_vdevice $ost))
19887         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19888         local zfs_zapid=$(do_facet $ost $cmd |
19889                           grep -w "/O/0/d$((objid%32))" -C 5 |
19890                           awk '/Object/{getline; print $1}')
19891         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19892                           awk "/$objid = /"'{printf $3}')
19893
19894         echo $zfs_objid
19895 }
19896
19897 zfs_object_blksz() {
19898         local ost=$1
19899         local objid=$2
19900
19901         local vdevdir=$(dirname $(facet_vdevice $ost))
19902         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19903         local blksz=$(do_facet $ost $cmd $objid |
19904                       awk '/dblk/{getline; printf $4}')
19905
19906         case "${blksz: -1}" in
19907                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19908                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19909                 *) ;;
19910         esac
19911
19912         echo $blksz
19913 }
19914
19915 test_312() { # LU-4856
19916         remote_ost_nodsh && skip "remote OST with nodsh"
19917         [ "$ost1_FSTYPE" = "zfs" ] ||
19918                 skip_env "the test only applies to zfs"
19919
19920         local max_blksz=$(do_facet ost1 \
19921                           $ZFS get -p recordsize $(facet_device ost1) |
19922                           awk '!/VALUE/{print $3}')
19923
19924         # to make life a little bit easier
19925         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19926         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19927
19928         local tf=$DIR/$tdir/$tfile
19929         touch $tf
19930         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19931
19932         # Get ZFS object id
19933         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19934         # block size change by sequential overwrite
19935         local bs
19936
19937         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19938                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19939
19940                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19941                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19942         done
19943         rm -f $tf
19944
19945         # block size change by sequential append write
19946         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19947         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19948         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19949         local count
19950
19951         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19952                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19953                         oflag=sync conv=notrunc
19954
19955                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19956                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19957                         error "blksz error, actual $blksz, " \
19958                                 "expected: 2 * $count * $PAGE_SIZE"
19959         done
19960         rm -f $tf
19961
19962         # random write
19963         touch $tf
19964         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19965         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19966
19967         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19968         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19969         [ $blksz -eq $PAGE_SIZE ] ||
19970                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19971
19972         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19973         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19974         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19975
19976         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19977         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19978         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19979 }
19980 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19981
19982 test_313() {
19983         remote_ost_nodsh && skip "remote OST with nodsh"
19984
19985         local file=$DIR/$tfile
19986
19987         rm -f $file
19988         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19989
19990         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19991         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19992         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19993                 error "write should failed"
19994         do_facet ost1 "$LCTL set_param fail_loc=0"
19995         rm -f $file
19996 }
19997 run_test 313 "io should fail after last_rcvd update fail"
19998
19999 test_314() {
20000         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
20001
20002         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
20003         do_facet ost1 "$LCTL set_param fail_loc=0x720"
20004         rm -f $DIR/$tfile
20005         wait_delete_completed
20006         do_facet ost1 "$LCTL set_param fail_loc=0"
20007 }
20008 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
20009
20010 test_315() { # LU-618
20011         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
20012
20013         local file=$DIR/$tfile
20014         rm -f $file
20015
20016         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
20017                 error "multiop file write failed"
20018         $MULTIOP $file oO_RDONLY:r4063232_c &
20019         PID=$!
20020
20021         sleep 2
20022
20023         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
20024         kill -USR1 $PID
20025
20026         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
20027         rm -f $file
20028 }
20029 run_test 315 "read should be accounted"
20030
20031 test_316() {
20032         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20033         large_xattr_enabled || skip_env "ea_inode feature disabled"
20034
20035         rm -rf $DIR/$tdir/d
20036         mkdir -p $DIR/$tdir/d
20037         chown nobody $DIR/$tdir/d
20038         touch $DIR/$tdir/d/file
20039
20040         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
20041 }
20042 run_test 316 "lfs mv"
20043
20044 test_317() {
20045         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
20046                 skip "Need MDS version at least 2.11.53"
20047         if [ "$ost1_FSTYPE" == "zfs" ]; then
20048                 skip "LU-10370: no implementation for ZFS"
20049         fi
20050
20051         local trunc_sz
20052         local grant_blk_size
20053
20054         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
20055                         awk '/grant_block_size:/ { print $2; exit; }')
20056         #
20057         # Create File of size 5M. Truncate it to below size's and verify
20058         # blocks count.
20059         #
20060         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
20061                 error "Create file $DIR/$tfile failed"
20062         stack_trap "rm -f $DIR/$tfile" EXIT
20063
20064         for trunc_sz in 2097152 4097 4000 509 0; do
20065                 $TRUNCATE $DIR/$tfile $trunc_sz ||
20066                         error "truncate $tfile to $trunc_sz failed"
20067                 local sz=$(stat --format=%s $DIR/$tfile)
20068                 local blk=$(stat --format=%b $DIR/$tfile)
20069                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
20070                                      grant_blk_size) * 8))
20071
20072                 if [[ $blk -ne $trunc_blk ]]; then
20073                         $(which stat) $DIR/$tfile
20074                         error "Expected Block $trunc_blk got $blk for $tfile"
20075                 fi
20076
20077                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20078                         error "Expected Size $trunc_sz got $sz for $tfile"
20079         done
20080
20081         #
20082         # sparse file test
20083         # Create file with a hole and write actual two blocks. Block count
20084         # must be 16.
20085         #
20086         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
20087                 conv=fsync || error "Create file : $DIR/$tfile"
20088
20089         # Calculate the final truncate size.
20090         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
20091
20092         #
20093         # truncate to size $trunc_sz bytes. Strip the last block
20094         # The block count must drop to 8
20095         #
20096         $TRUNCATE $DIR/$tfile $trunc_sz ||
20097                 error "truncate $tfile to $trunc_sz failed"
20098
20099         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
20100         sz=$(stat --format=%s $DIR/$tfile)
20101         blk=$(stat --format=%b $DIR/$tfile)
20102
20103         if [[ $blk -ne $trunc_bsz ]]; then
20104                 $(which stat) $DIR/$tfile
20105                 error "Expected Block $trunc_bsz got $blk for $tfile"
20106         fi
20107
20108         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
20109                 error "Expected Size $trunc_sz got $sz for $tfile"
20110 }
20111 run_test 317 "Verify blocks get correctly update after truncate"
20112
20113 test_318() {
20114         local old_max_active=$($LCTL get_param -n \
20115                             llite.*.max_read_ahead_async_active 2>/dev/null)
20116
20117         $LCTL set_param llite.*.max_read_ahead_async_active=256
20118         local max_active=$($LCTL get_param -n \
20119                            llite.*.max_read_ahead_async_active 2>/dev/null)
20120         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
20121
20122         # currently reset to 0 is unsupported, leave it 512 for now.
20123         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
20124                 error "set max_read_ahead_async_active should fail"
20125
20126         $LCTL set_param llite.*.max_read_ahead_async_active=512
20127         max_active=$($LCTL get_param -n \
20128                      llite.*.max_read_ahead_async_active 2>/dev/null)
20129         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
20130
20131         # restore @max_active
20132         [ $old_max_active -ne 0 ] && $LCTL set_param \
20133                 llite.*.max_read_ahead_async_active=$old_max_active
20134
20135         local old_threshold=$($LCTL get_param -n \
20136                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20137         local max_per_file_mb=$($LCTL get_param -n \
20138                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
20139
20140         local invalid=$(($max_per_file_mb + 1))
20141         $LCTL set_param \
20142                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
20143                         && error "set $invalid should fail"
20144
20145         local valid=$(($invalid - 1))
20146         $LCTL set_param \
20147                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
20148                         error "set $valid should succeed"
20149         local threshold=$($LCTL get_param -n \
20150                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
20151         [ $threshold -eq $valid ] || error \
20152                 "expect threshold $valid got $threshold"
20153         $LCTL set_param \
20154                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
20155 }
20156 run_test 318 "Verify async readahead tunables"
20157
20158 test_319() {
20159         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
20160
20161         local before=$(date +%s)
20162         local evict
20163         local mdir=$DIR/$tdir
20164         local file=$mdir/xxx
20165
20166         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
20167         touch $file
20168
20169 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
20170         $LCTL set_param fail_val=5 fail_loc=0x8000032c
20171         $LFS mv -m1 $file &
20172
20173         sleep 1
20174         dd if=$file of=/dev/null
20175         wait
20176         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
20177           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
20178
20179         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
20180 }
20181 run_test 319 "lost lease lock on migrate error"
20182
20183 test_fake_rw() {
20184         local read_write=$1
20185         if [ "$read_write" = "write" ]; then
20186                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20187         elif [ "$read_write" = "read" ]; then
20188                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20189         else
20190                 error "argument error"
20191         fi
20192
20193         # turn off debug for performance testing
20194         local saved_debug=$($LCTL get_param -n debug)
20195         $LCTL set_param debug=0
20196
20197         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20198
20199         # get ost1 size - lustre-OST0000
20200         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20201         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20202         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20203
20204         if [ "$read_write" = "read" ]; then
20205                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20206         fi
20207
20208         local start_time=$(date +%s.%N)
20209         $dd_cmd bs=1M count=$blocks oflag=sync ||
20210                 error "real dd $read_write error"
20211         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20212
20213         if [ "$read_write" = "write" ]; then
20214                 rm -f $DIR/$tfile
20215         fi
20216
20217         # define OBD_FAIL_OST_FAKE_RW           0x238
20218         do_facet ost1 $LCTL set_param fail_loc=0x238
20219
20220         local start_time=$(date +%s.%N)
20221         $dd_cmd bs=1M count=$blocks oflag=sync ||
20222                 error "fake dd $read_write error"
20223         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20224
20225         if [ "$read_write" = "write" ]; then
20226                 # verify file size
20227                 cancel_lru_locks osc
20228                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20229                         error "$tfile size not $blocks MB"
20230         fi
20231         do_facet ost1 $LCTL set_param fail_loc=0
20232
20233         echo "fake $read_write $duration_fake vs. normal $read_write" \
20234                 "$duration in seconds"
20235         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20236                 error_not_in_vm "fake write is slower"
20237
20238         $LCTL set_param -n debug="$saved_debug"
20239         rm -f $DIR/$tfile
20240 }
20241 test_399a() { # LU-7655 for OST fake write
20242         remote_ost_nodsh && skip "remote OST with nodsh"
20243
20244         test_fake_rw write
20245 }
20246 run_test 399a "fake write should not be slower than normal write"
20247
20248 test_399b() { # LU-8726 for OST fake read
20249         remote_ost_nodsh && skip "remote OST with nodsh"
20250         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20251                 skip_env "ldiskfs only test"
20252         fi
20253
20254         test_fake_rw read
20255 }
20256 run_test 399b "fake read should not be slower than normal read"
20257
20258 test_400a() { # LU-1606, was conf-sanity test_74
20259         if ! which $CC > /dev/null 2>&1; then
20260                 skip_env "$CC is not installed"
20261         fi
20262
20263         local extra_flags=''
20264         local out=$TMP/$tfile
20265         local prefix=/usr/include/lustre
20266         local prog
20267
20268         if ! [[ -d $prefix ]]; then
20269                 # Assume we're running in tree and fixup the include path.
20270                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20271                 extra_flags+=" -L$LUSTRE/utils/.lib"
20272         fi
20273
20274         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20275                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20276                         error "client api broken"
20277         done
20278         rm -f $out
20279 }
20280 run_test 400a "Lustre client api program can compile and link"
20281
20282 test_400b() { # LU-1606, LU-5011
20283         local header
20284         local out=$TMP/$tfile
20285         local prefix=/usr/include/linux/lustre
20286
20287         # We use a hard coded prefix so that this test will not fail
20288         # when run in tree. There are headers in lustre/include/lustre/
20289         # that are not packaged (like lustre_idl.h) and have more
20290         # complicated include dependencies (like config.h and lnet/types.h).
20291         # Since this test about correct packaging we just skip them when
20292         # they don't exist (see below) rather than try to fixup cppflags.
20293
20294         if ! which $CC > /dev/null 2>&1; then
20295                 skip_env "$CC is not installed"
20296         fi
20297
20298         for header in $prefix/*.h; do
20299                 if ! [[ -f "$header" ]]; then
20300                         continue
20301                 fi
20302
20303                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20304                         continue # lustre_ioctl.h is internal header
20305                 fi
20306
20307                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20308                         error "cannot compile '$header'"
20309         done
20310         rm -f $out
20311 }
20312 run_test 400b "packaged headers can be compiled"
20313
20314 test_401a() { #LU-7437
20315         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20316         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20317
20318         #count the number of parameters by "list_param -R"
20319         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20320         #count the number of parameters by listing proc files
20321         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20322         echo "proc_dirs='$proc_dirs'"
20323         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20324         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20325                       sort -u | wc -l)
20326
20327         [ $params -eq $procs ] ||
20328                 error "found $params parameters vs. $procs proc files"
20329
20330         # test the list_param -D option only returns directories
20331         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20332         #count the number of parameters by listing proc directories
20333         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20334                 sort -u | wc -l)
20335
20336         [ $params -eq $procs ] ||
20337                 error "found $params parameters vs. $procs proc files"
20338 }
20339 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20340
20341 test_401b() {
20342         local save=$($LCTL get_param -n jobid_var)
20343         local tmp=testing
20344
20345         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20346                 error "no error returned when setting bad parameters"
20347
20348         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20349         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20350
20351         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20352         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20353         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20354 }
20355 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20356
20357 test_401c() {
20358         local jobid_var_old=$($LCTL get_param -n jobid_var)
20359         local jobid_var_new
20360
20361         $LCTL set_param jobid_var= &&
20362                 error "no error returned for 'set_param a='"
20363
20364         jobid_var_new=$($LCTL get_param -n jobid_var)
20365         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20366                 error "jobid_var was changed by setting without value"
20367
20368         $LCTL set_param jobid_var &&
20369                 error "no error returned for 'set_param a'"
20370
20371         jobid_var_new=$($LCTL get_param -n jobid_var)
20372         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20373                 error "jobid_var was changed by setting without value"
20374 }
20375 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20376
20377 test_401d() {
20378         local jobid_var_old=$($LCTL get_param -n jobid_var)
20379         local jobid_var_new
20380         local new_value="foo=bar"
20381
20382         $LCTL set_param jobid_var=$new_value ||
20383                 error "'set_param a=b' did not accept a value containing '='"
20384
20385         jobid_var_new=$($LCTL get_param -n jobid_var)
20386         [[ "$jobid_var_new" == "$new_value" ]] ||
20387                 error "'set_param a=b' failed on a value containing '='"
20388
20389         # Reset the jobid_var to test the other format
20390         $LCTL set_param jobid_var=$jobid_var_old
20391         jobid_var_new=$($LCTL get_param -n jobid_var)
20392         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20393                 error "failed to reset jobid_var"
20394
20395         $LCTL set_param jobid_var $new_value ||
20396                 error "'set_param a b' did not accept a value containing '='"
20397
20398         jobid_var_new=$($LCTL get_param -n jobid_var)
20399         [[ "$jobid_var_new" == "$new_value" ]] ||
20400                 error "'set_param a b' failed on a value containing '='"
20401
20402         $LCTL set_param jobid_var $jobid_var_old
20403         jobid_var_new=$($LCTL get_param -n jobid_var)
20404         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20405                 error "failed to reset jobid_var"
20406 }
20407 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20408
20409 test_402() {
20410         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20411         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20412                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20413         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20414                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20415                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20416         remote_mds_nodsh && skip "remote MDS with nodsh"
20417
20418         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20419 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20420         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20421         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20422                 echo "Touch failed - OK"
20423 }
20424 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20425
20426 test_403() {
20427         local file1=$DIR/$tfile.1
20428         local file2=$DIR/$tfile.2
20429         local tfile=$TMP/$tfile
20430
20431         rm -f $file1 $file2 $tfile
20432
20433         touch $file1
20434         ln $file1 $file2
20435
20436         # 30 sec OBD_TIMEOUT in ll_getattr()
20437         # right before populating st_nlink
20438         $LCTL set_param fail_loc=0x80001409
20439         stat -c %h $file1 > $tfile &
20440
20441         # create an alias, drop all locks and reclaim the dentry
20442         < $file2
20443         cancel_lru_locks mdc
20444         cancel_lru_locks osc
20445         sysctl -w vm.drop_caches=2
20446
20447         wait
20448
20449         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20450
20451         rm -f $tfile $file1 $file2
20452 }
20453 run_test 403 "i_nlink should not drop to zero due to aliasing"
20454
20455 test_404() { # LU-6601
20456         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20457                 skip "Need server version newer than 2.8.52"
20458         remote_mds_nodsh && skip "remote MDS with nodsh"
20459
20460         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20461                 awk '/osp .*-osc-MDT/ { print $4}')
20462
20463         local osp
20464         for osp in $mosps; do
20465                 echo "Deactivate: " $osp
20466                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20467                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20468                         awk -vp=$osp '$4 == p { print $2 }')
20469                 [ $stat = IN ] || {
20470                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20471                         error "deactivate error"
20472                 }
20473                 echo "Activate: " $osp
20474                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20475                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20476                         awk -vp=$osp '$4 == p { print $2 }')
20477                 [ $stat = UP ] || {
20478                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20479                         error "activate error"
20480                 }
20481         done
20482 }
20483 run_test 404 "validate manual {de}activated works properly for OSPs"
20484
20485 test_405() {
20486         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20487         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20488                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20489                         skip "Layout swap lock is not supported"
20490
20491         check_swap_layouts_support
20492
20493         test_mkdir $DIR/$tdir
20494         swap_lock_test -d $DIR/$tdir ||
20495                 error "One layout swap locked test failed"
20496 }
20497 run_test 405 "Various layout swap lock tests"
20498
20499 test_406() {
20500         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20501         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20502         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20504         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20505                 skip "Need MDS version at least 2.8.50"
20506
20507         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20508         local test_pool=$TESTNAME
20509
20510         pool_add $test_pool || error "pool_add failed"
20511         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20512                 error "pool_add_targets failed"
20513
20514         save_layout_restore_at_exit $MOUNT
20515
20516         # parent set default stripe count only, child will stripe from both
20517         # parent and fs default
20518         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20519                 error "setstripe $MOUNT failed"
20520         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20521         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20522         for i in $(seq 10); do
20523                 local f=$DIR/$tdir/$tfile.$i
20524                 touch $f || error "touch failed"
20525                 local count=$($LFS getstripe -c $f)
20526                 [ $count -eq $OSTCOUNT ] ||
20527                         error "$f stripe count $count != $OSTCOUNT"
20528                 local offset=$($LFS getstripe -i $f)
20529                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20530                 local size=$($LFS getstripe -S $f)
20531                 [ $size -eq $((def_stripe_size * 2)) ] ||
20532                         error "$f stripe size $size != $((def_stripe_size * 2))"
20533                 local pool=$($LFS getstripe -p $f)
20534                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20535         done
20536
20537         # change fs default striping, delete parent default striping, now child
20538         # will stripe from new fs default striping only
20539         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20540                 error "change $MOUNT default stripe failed"
20541         $LFS setstripe -c 0 $DIR/$tdir ||
20542                 error "delete $tdir default stripe failed"
20543         for i in $(seq 11 20); do
20544                 local f=$DIR/$tdir/$tfile.$i
20545                 touch $f || error "touch $f failed"
20546                 local count=$($LFS getstripe -c $f)
20547                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20548                 local offset=$($LFS getstripe -i $f)
20549                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20550                 local size=$($LFS getstripe -S $f)
20551                 [ $size -eq $def_stripe_size ] ||
20552                         error "$f stripe size $size != $def_stripe_size"
20553                 local pool=$($LFS getstripe -p $f)
20554                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20555         done
20556
20557         unlinkmany $DIR/$tdir/$tfile. 1 20
20558
20559         local f=$DIR/$tdir/$tfile
20560         pool_remove_all_targets $test_pool $f
20561         pool_remove $test_pool $f
20562 }
20563 run_test 406 "DNE support fs default striping"
20564
20565 test_407() {
20566         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20567         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20568                 skip "Need MDS version at least 2.8.55"
20569         remote_mds_nodsh && skip "remote MDS with nodsh"
20570
20571         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20572                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20573         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20574                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20575         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20576
20577         #define OBD_FAIL_DT_TXN_STOP    0x2019
20578         for idx in $(seq $MDSCOUNT); do
20579                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20580         done
20581         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20582         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20583                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20584         true
20585 }
20586 run_test 407 "transaction fail should cause operation fail"
20587
20588 test_408() {
20589         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20590
20591         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20592         lctl set_param fail_loc=0x8000040a
20593         # let ll_prepare_partial_page() fail
20594         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20595
20596         rm -f $DIR/$tfile
20597
20598         # create at least 100 unused inodes so that
20599         # shrink_icache_memory(0) should not return 0
20600         touch $DIR/$tfile-{0..100}
20601         rm -f $DIR/$tfile-{0..100}
20602         sync
20603
20604         echo 2 > /proc/sys/vm/drop_caches
20605 }
20606 run_test 408 "drop_caches should not hang due to page leaks"
20607
20608 test_409()
20609 {
20610         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20611
20612         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20613         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20614         touch $DIR/$tdir/guard || error "(2) Fail to create"
20615
20616         local PREFIX=$(str_repeat 'A' 128)
20617         echo "Create 1K hard links start at $(date)"
20618         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20619                 error "(3) Fail to hard link"
20620
20621         echo "Links count should be right although linkEA overflow"
20622         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20623         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20624         [ $linkcount -eq 1001 ] ||
20625                 error "(5) Unexpected hard links count: $linkcount"
20626
20627         echo "List all links start at $(date)"
20628         ls -l $DIR/$tdir/foo > /dev/null ||
20629                 error "(6) Fail to list $DIR/$tdir/foo"
20630
20631         echo "Unlink hard links start at $(date)"
20632         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20633                 error "(7) Fail to unlink"
20634         echo "Unlink hard links finished at $(date)"
20635 }
20636 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20637
20638 test_410()
20639 {
20640         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20641                 skip "Need client version at least 2.9.59"
20642
20643         # Create a file, and stat it from the kernel
20644         local testfile=$DIR/$tfile
20645         touch $testfile
20646
20647         local run_id=$RANDOM
20648         local my_ino=$(stat --format "%i" $testfile)
20649
20650         # Try to insert the module. This will always fail as the
20651         # module is designed to not be inserted.
20652         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20653             &> /dev/null
20654
20655         # Anything but success is a test failure
20656         dmesg | grep -q \
20657             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20658             error "no inode match"
20659 }
20660 run_test 410 "Test inode number returned from kernel thread"
20661
20662 cleanup_test411_cgroup() {
20663         trap 0
20664         rmdir "$1"
20665 }
20666
20667 test_411() {
20668         local cg_basedir=/sys/fs/cgroup/memory
20669         # LU-9966
20670         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20671                 skip "no setup for cgroup"
20672
20673         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20674                 error "test file creation failed"
20675         cancel_lru_locks osc
20676
20677         # Create a very small memory cgroup to force a slab allocation error
20678         local cgdir=$cg_basedir/osc_slab_alloc
20679         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20680         trap "cleanup_test411_cgroup $cgdir" EXIT
20681         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20682         echo 1M > $cgdir/memory.limit_in_bytes
20683
20684         # Should not LBUG, just be killed by oom-killer
20685         # dd will return 0 even allocation failure in some environment.
20686         # So don't check return value
20687         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20688         cleanup_test411_cgroup $cgdir
20689
20690         return 0
20691 }
20692 run_test 411 "Slab allocation error with cgroup does not LBUG"
20693
20694 test_412() {
20695         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20696         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20697                 skip "Need server version at least 2.10.55"
20698         fi
20699
20700         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20701                 error "mkdir failed"
20702         $LFS getdirstripe $DIR/$tdir
20703         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20704         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20705                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20706         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20707         [ $stripe_count -eq 2 ] ||
20708                 error "expect 2 get $stripe_count"
20709 }
20710 run_test 412 "mkdir on specific MDTs"
20711
20712 test_413a() {
20713         [ $MDSCOUNT -lt 2 ] &&
20714                 skip "We need at least 2 MDTs for this test"
20715
20716         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20717                 skip "Need server version at least 2.10.55"
20718         fi
20719
20720         mkdir $DIR/$tdir || error "mkdir failed"
20721
20722         # find MDT that is the most full
20723         local max=$($LFS df | grep MDT |
20724                 awk 'BEGIN { a=0 }
20725                         { sub("%", "", $5)
20726                           if (0+$5 >= a)
20727                           {
20728                                 a = $5
20729                                 b = $6
20730                           }
20731                         }
20732                      END { split(b, c, ":")
20733                            sub("]", "", c[2])
20734                            print c[2]
20735                          }')
20736
20737         for i in $(seq $((MDSCOUNT - 1))); do
20738                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20739                         error "mkdir d$i failed"
20740                 $LFS getdirstripe $DIR/$tdir/d$i
20741                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20742                 [ $stripe_index -ne $max ] ||
20743                         error "don't expect $max"
20744         done
20745 }
20746 run_test 413a "mkdir on less full MDTs"
20747
20748 test_413b() {
20749         [ $MDSCOUNT -lt 2 ] &&
20750                 skip "We need at least 2 MDTs for this test"
20751
20752         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20753                 skip "Need server version at least 2.12.52"
20754
20755         mkdir $DIR/$tdir || error "mkdir failed"
20756         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20757                 error "setdirstripe failed"
20758
20759         local qos_prio_free
20760         local qos_threshold_rr
20761         local count
20762
20763         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20764         qos_prio_free=${qos_prio_free%%%}
20765         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20766         qos_threshold_rr=${qos_threshold_rr%%%}
20767         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20768
20769         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20770         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20771                 EXIT
20772         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20773
20774         echo "mkdir with roundrobin"
20775
20776         $LCTL set_param lmv.*.qos_threshold_rr=100
20777         for i in $(seq $((100 * MDSCOUNT))); do
20778                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20779         done
20780         for i in $(seq $MDSCOUNT); do
20781                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20782                         wc -w)
20783                 echo "$count directories created on MDT$((i - 1))"
20784                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20785         done
20786
20787         rm -rf $DIR/$tdir/*
20788
20789         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20790         # Shorten statfs result age, so that it can be updated in time
20791         $LCTL set_param lmv.*.qos_maxage=1
20792         sleep_maxage
20793
20794         local ffree
20795         local bavail
20796         local max
20797         local min
20798         local max_index
20799         local min_index
20800         local tmp
20801
20802         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree))
20803         bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.kbytesavail))
20804         bsize=$(lctl get_param -n mdc.*MDT0000*.blocksize)
20805
20806         max=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20807         min=$(((${ffree[0]} >> 8) * (${bavail[0]} * bsize >> 16)))
20808         max_index=0
20809         min_index=0
20810         for ((i = 1; i < ${#ffree[@]}; i++)); do
20811                 tmp=$(((${ffree[i]} >> 8) * (${bavail[i]} * bsize >> 16)))
20812                 if [ $tmp -gt $max ]; then
20813                         max=$tmp
20814                         max_index=$i
20815                 fi
20816                 if [ $tmp -lt $min ]; then
20817                         min=$tmp
20818                         min_index=$i
20819                 fi
20820         done
20821
20822         [ ${ffree[min_index]} -eq 0 ] &&
20823                 skip "no free files in MDT$min_index"
20824         [ ${ffree[min_index]} -gt 100000000 ] &&
20825                 skip "too much free files in MDT$min_index"
20826
20827         # Check if we need to generate uneven MDTs
20828         local threshold=50
20829         local diff=$(((max - min ) * 100 / min))
20830         local value="$(generate_string 1024)"
20831         local i
20832
20833         while [ $diff -lt $threshold ]; do
20834                 # generate uneven MDTs, create till $threshold% diff
20835                 echo -n "weight diff=$diff% must be > $threshold% ..."
20836                 count=$((${ffree[min_index]} / 10))
20837                 # 50 sec per 10000 files in vm
20838                 [ $count -gt 40000 ] && [ "$SLOW" = "no" ] &&
20839                         skip "$count files to create"
20840                 echo "Fill MDT$min_index with $count files"
20841                 [ -d $DIR/$tdir-MDT$min_index ] ||
20842                         $LFS mkdir -i $min_index $DIR/$tdir-MDT$min_index ||
20843                         error "mkdir $tdir-MDT$min_index failed"
20844                 for i in $(seq $count); do
20845                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20846                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20847                                 error "create f$i failed"
20848                         setfattr -n user.413b -v $value \
20849                                 $DIR/$tdir-MDT$min_index/f$i ||
20850                                 error "setfattr f$i failed"
20851                 done
20852
20853                 ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-*.filesfree))
20854                 bavail=($(lctl get_param -n mdc.*[mM][dD][cC]-*.kbytesavail))
20855                 max=$(((${ffree[max_index]} >> 8) * \
20856                         (${bavail[max_index]} * bsize >> 16)))
20857                 min=$(((${ffree[min_index]} >> 8) * \
20858                         (${bavail[min_index]} * bsize >> 16)))
20859                 diff=$(((max - min) * 100 / min))
20860         done
20861
20862         echo "MDT filesfree available: ${ffree[@]}"
20863         echo "MDT blocks available: ${bavail[@]}"
20864         echo "weight diff=$diff%"
20865
20866         echo "mkdir with balanced space usage"
20867         $LCTL set_param lmv.*.qos_prio_free=100
20868         for i in $(seq $((100 * MDSCOUNT))); do
20869                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20870         done
20871
20872         for i in $(seq $MDSCOUNT); do
20873                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20874                         wc -w)
20875                 echo "$count directories created on MDT$((i - 1))"
20876         done
20877
20878         max=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$max_index$ | wc -l)
20879         min=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$min_index$ | wc -l)
20880
20881         [ $((max - min)) -lt 10 ] &&
20882                 error "subdirs shouldn't be evenly distributed"
20883
20884         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20885
20886         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20887         getfattr -n trusted.dmv $DIR/$tdir &&
20888                 error "default dir layout exists" || true
20889 }
20890 run_test 413b "mkdir with balanced space usage"
20891
20892 test_414() {
20893 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20894         $LCTL set_param fail_loc=0x80000521
20895         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20896         rm -f $DIR/$tfile
20897 }
20898 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20899
20900 test_415() {
20901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20902         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20903                 skip "Need server version at least 2.11.52"
20904
20905         # LU-11102
20906         local total
20907         local setattr_pid
20908         local start_time
20909         local end_time
20910         local duration
20911
20912         total=500
20913         # this test may be slow on ZFS
20914         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20915
20916         # though this test is designed for striped directory, let's test normal
20917         # directory too since lock is always saved as CoS lock.
20918         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20919         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20920
20921         (
20922                 while true; do
20923                         touch $DIR/$tdir
20924                 done
20925         ) &
20926         setattr_pid=$!
20927
20928         start_time=$(date +%s)
20929         for i in $(seq $total); do
20930                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20931                         > /dev/null
20932         done
20933         end_time=$(date +%s)
20934         duration=$((end_time - start_time))
20935
20936         kill -9 $setattr_pid
20937
20938         echo "rename $total files took $duration sec"
20939         [ $duration -lt 100 ] || error "rename took $duration sec"
20940 }
20941 run_test 415 "lock revoke is not missing"
20942
20943 test_416() {
20944         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20945                 skip "Need server version at least 2.11.55"
20946
20947         # define OBD_FAIL_OSD_TXN_START    0x19a
20948         do_facet mds1 lctl set_param fail_loc=0x19a
20949
20950         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20951
20952         true
20953 }
20954 run_test 416 "transaction start failure won't cause system hung"
20955
20956 cleanup_417() {
20957         trap 0
20958         do_nodes $(comma_list $(mdts_nodes)) \
20959                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20960         do_nodes $(comma_list $(mdts_nodes)) \
20961                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20962         do_nodes $(comma_list $(mdts_nodes)) \
20963                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20964 }
20965
20966 test_417() {
20967         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20968         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20969                 skip "Need MDS version at least 2.11.56"
20970
20971         trap cleanup_417 RETURN EXIT
20972
20973         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20974         do_nodes $(comma_list $(mdts_nodes)) \
20975                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20976         $LFS migrate -m 0 $DIR/$tdir.1 &&
20977                 error "migrate dir $tdir.1 should fail"
20978
20979         do_nodes $(comma_list $(mdts_nodes)) \
20980                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20981         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20982                 error "create remote dir $tdir.2 should fail"
20983
20984         do_nodes $(comma_list $(mdts_nodes)) \
20985                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20986         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20987                 error "create striped dir $tdir.3 should fail"
20988         true
20989 }
20990 run_test 417 "disable remote dir, striped dir and dir migration"
20991
20992 # Checks that the outputs of df [-i] and lfs df [-i] match
20993 #
20994 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20995 check_lfs_df() {
20996         local dir=$2
20997         local inodes
20998         local df_out
20999         local lfs_df_out
21000         local count
21001         local passed=false
21002
21003         # blocks or inodes
21004         [ "$1" == "blocks" ] && inodes= || inodes="-i"
21005
21006         for count in {1..100}; do
21007                 cancel_lru_locks
21008                 sync; sleep 0.2
21009
21010                 # read the lines of interest
21011                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
21012                         error "df $inodes $dir | tail -n +2 failed"
21013                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
21014                         error "lfs df $inodes $dir | grep summary: failed"
21015
21016                 # skip first substrings of each output as they are different
21017                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
21018                 # compare the two outputs
21019                 passed=true
21020                 for i in {1..5}; do
21021                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
21022                 done
21023                 $passed && break
21024         done
21025
21026         if ! $passed; then
21027                 df -P $inodes $dir
21028                 echo
21029                 lfs df $inodes $dir
21030                 error "df and lfs df $1 output mismatch: "      \
21031                       "df ${inodes}: ${df_out[*]}, "            \
21032                       "lfs df ${inodes}: ${lfs_df_out[*]}"
21033         fi
21034 }
21035
21036 test_418() {
21037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21038
21039         local dir=$DIR/$tdir
21040         local numfiles=$((RANDOM % 4096 + 2))
21041         local numblocks=$((RANDOM % 256 + 1))
21042
21043         wait_delete_completed
21044         test_mkdir $dir
21045
21046         # check block output
21047         check_lfs_df blocks $dir
21048         # check inode output
21049         check_lfs_df inodes $dir
21050
21051         # create a single file and retest
21052         echo "Creating a single file and testing"
21053         createmany -o $dir/$tfile- 1 &>/dev/null ||
21054                 error "creating 1 file in $dir failed"
21055         check_lfs_df blocks $dir
21056         check_lfs_df inodes $dir
21057
21058         # create a random number of files
21059         echo "Creating $((numfiles - 1)) files and testing"
21060         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
21061                 error "creating $((numfiles - 1)) files in $dir failed"
21062
21063         # write a random number of blocks to the first test file
21064         echo "Writing $numblocks 4K blocks and testing"
21065         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
21066                 count=$numblocks &>/dev/null ||
21067                 error "dd to $dir/${tfile}-0 failed"
21068
21069         # retest
21070         check_lfs_df blocks $dir
21071         check_lfs_df inodes $dir
21072
21073         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
21074                 error "unlinking $numfiles files in $dir failed"
21075 }
21076 run_test 418 "df and lfs df outputs match"
21077
21078 test_419()
21079 {
21080         local dir=$DIR/$tdir
21081
21082         mkdir -p $dir
21083         touch $dir/file
21084
21085         cancel_lru_locks mdc
21086
21087         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
21088         $LCTL set_param fail_loc=0x1410
21089         cat $dir/file
21090         $LCTL set_param fail_loc=0
21091         rm -rf $dir
21092 }
21093 run_test 419 "Verify open file by name doesn't crash kernel"
21094
21095 test_420()
21096 {
21097         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
21098                 skip "Need MDS version at least 2.12.53"
21099
21100         local SAVE_UMASK=$(umask)
21101         local dir=$DIR/$tdir
21102         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
21103
21104         mkdir -p $dir
21105         umask 0000
21106         mkdir -m03777 $dir/testdir
21107         ls -dn $dir/testdir
21108         # Need to remove trailing '.' when SELinux is enabled
21109         local dirperms=$(ls -dn $dir/testdir |
21110                          awk '{ sub(/\.$/, "", $1); print $1}')
21111         [ $dirperms == "drwxrwsrwt" ] ||
21112                 error "incorrect perms on $dir/testdir"
21113
21114         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
21115                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
21116         ls -n $dir/testdir/testfile
21117         local fileperms=$(ls -n $dir/testdir/testfile |
21118                           awk '{ sub(/\.$/, "", $1); print $1}')
21119         [ $fileperms == "-rwxr-xr-x" ] ||
21120                 error "incorrect perms on $dir/testdir/testfile"
21121
21122         umask $SAVE_UMASK
21123 }
21124 run_test 420 "clear SGID bit on non-directories for non-members"
21125
21126 test_421a() {
21127         local cnt
21128         local fid1
21129         local fid2
21130
21131         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21132                 skip "Need MDS version at least 2.12.54"
21133
21134         test_mkdir $DIR/$tdir
21135         createmany -o $DIR/$tdir/f 3
21136         cnt=$(ls -1 $DIR/$tdir | wc -l)
21137         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21138
21139         fid1=$(lfs path2fid $DIR/$tdir/f1)
21140         fid2=$(lfs path2fid $DIR/$tdir/f2)
21141         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
21142
21143         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
21144         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
21145
21146         cnt=$(ls -1 $DIR/$tdir | wc -l)
21147         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21148
21149         rm -f $DIR/$tdir/f3 || error "can't remove f3"
21150         createmany -o $DIR/$tdir/f 3
21151         cnt=$(ls -1 $DIR/$tdir | wc -l)
21152         [ $cnt != 3 ] && error "unexpected #files: $cnt"
21153
21154         fid1=$(lfs path2fid $DIR/$tdir/f1)
21155         fid2=$(lfs path2fid $DIR/$tdir/f2)
21156         echo "remove using fsname $FSNAME"
21157         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
21158
21159         cnt=$(ls -1 $DIR/$tdir | wc -l)
21160         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
21161 }
21162 run_test 421a "simple rm by fid"
21163
21164 test_421b() {
21165         local cnt
21166         local FID1
21167         local FID2
21168
21169         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21170                 skip "Need MDS version at least 2.12.54"
21171
21172         test_mkdir $DIR/$tdir
21173         createmany -o $DIR/$tdir/f 3
21174         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
21175         MULTIPID=$!
21176
21177         FID1=$(lfs path2fid $DIR/$tdir/f1)
21178         FID2=$(lfs path2fid $DIR/$tdir/f2)
21179         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
21180
21181         kill -USR1 $MULTIPID
21182         wait
21183
21184         cnt=$(ls $DIR/$tdir | wc -l)
21185         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
21186 }
21187 run_test 421b "rm by fid on open file"
21188
21189 test_421c() {
21190         local cnt
21191         local FIDS
21192
21193         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21194                 skip "Need MDS version at least 2.12.54"
21195
21196         test_mkdir $DIR/$tdir
21197         createmany -o $DIR/$tdir/f 3
21198         touch $DIR/$tdir/$tfile
21199         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21200         cnt=$(ls -1 $DIR/$tdir | wc -l)
21201         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21202
21203         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21204         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21205
21206         cnt=$(ls $DIR/$tdir | wc -l)
21207         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21208 }
21209 run_test 421c "rm by fid against hardlinked files"
21210
21211 test_421d() {
21212         local cnt
21213         local FIDS
21214
21215         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21216                 skip "Need MDS version at least 2.12.54"
21217
21218         test_mkdir $DIR/$tdir
21219         createmany -o $DIR/$tdir/f 4097
21220         cnt=$(ls -1 $DIR/$tdir | wc -l)
21221         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21222
21223         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21224         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21225
21226         cnt=$(ls $DIR/$tdir | wc -l)
21227         rm -rf $DIR/$tdir
21228         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21229 }
21230 run_test 421d "rmfid en masse"
21231
21232 test_421e() {
21233         local cnt
21234         local FID
21235
21236         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21237         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21238                 skip "Need MDS version at least 2.12.54"
21239
21240         mkdir -p $DIR/$tdir
21241         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21242         createmany -o $DIR/$tdir/striped_dir/f 512
21243         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21244         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21245
21246         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21247                 sed "s/[/][^:]*://g")
21248         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21249
21250         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21251         rm -rf $DIR/$tdir
21252         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21253 }
21254 run_test 421e "rmfid in DNE"
21255
21256 test_421f() {
21257         local cnt
21258         local FID
21259
21260         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21261                 skip "Need MDS version at least 2.12.54"
21262
21263         test_mkdir $DIR/$tdir
21264         touch $DIR/$tdir/f
21265         cnt=$(ls -1 $DIR/$tdir | wc -l)
21266         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21267
21268         FID=$(lfs path2fid $DIR/$tdir/f)
21269         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21270         # rmfid should fail
21271         cnt=$(ls -1 $DIR/$tdir | wc -l)
21272         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21273
21274         chmod a+rw $DIR/$tdir
21275         ls -la $DIR/$tdir
21276         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21277         # rmfid should fail
21278         cnt=$(ls -1 $DIR/$tdir | wc -l)
21279         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21280
21281         rm -f $DIR/$tdir/f
21282         $RUNAS touch $DIR/$tdir/f
21283         FID=$(lfs path2fid $DIR/$tdir/f)
21284         echo "rmfid as root"
21285         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21286         cnt=$(ls -1 $DIR/$tdir | wc -l)
21287         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21288
21289         rm -f $DIR/$tdir/f
21290         $RUNAS touch $DIR/$tdir/f
21291         cnt=$(ls -1 $DIR/$tdir | wc -l)
21292         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21293         FID=$(lfs path2fid $DIR/$tdir/f)
21294         # rmfid w/o user_fid2path mount option should fail
21295         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21296         cnt=$(ls -1 $DIR/$tdir | wc -l)
21297         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21298
21299         umount_client $MOUNT || error "failed to umount client"
21300         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21301                 error "failed to mount client'"
21302
21303         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21304         # rmfid should succeed
21305         cnt=$(ls -1 $DIR/$tdir | wc -l)
21306         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21307
21308         # rmfid shouldn't allow to remove files due to dir's permission
21309         chmod a+rwx $DIR/$tdir
21310         touch $DIR/$tdir/f
21311         ls -la $DIR/$tdir
21312         FID=$(lfs path2fid $DIR/$tdir/f)
21313         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21314
21315         umount_client $MOUNT || error "failed to umount client"
21316         mount_client $MOUNT "$MOUNT_OPTS" ||
21317                 error "failed to mount client'"
21318
21319 }
21320 run_test 421f "rmfid checks permissions"
21321
21322 test_421g() {
21323         local cnt
21324         local FIDS
21325
21326         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21327         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21328                 skip "Need MDS version at least 2.12.54"
21329
21330         mkdir -p $DIR/$tdir
21331         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21332         createmany -o $DIR/$tdir/striped_dir/f 512
21333         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21334         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21335
21336         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21337                 sed "s/[/][^:]*://g")
21338
21339         rm -f $DIR/$tdir/striped_dir/f1*
21340         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21341         removed=$((512 - cnt))
21342
21343         # few files have been just removed, so we expect
21344         # rmfid to fail on their fids
21345         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21346         [ $removed != $errors ] && error "$errors != $removed"
21347
21348         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21349         rm -rf $DIR/$tdir
21350         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21351 }
21352 run_test 421g "rmfid to return errors properly"
21353
21354 prep_801() {
21355         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21356         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21357                 skip "Need server version at least 2.9.55"
21358
21359         start_full_debug_logging
21360 }
21361
21362 post_801() {
21363         stop_full_debug_logging
21364 }
21365
21366 barrier_stat() {
21367         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21368                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21369                            awk '/The barrier for/ { print $7 }')
21370                 echo $st
21371         else
21372                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21373                 echo \'$st\'
21374         fi
21375 }
21376
21377 barrier_expired() {
21378         local expired
21379
21380         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21381                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21382                           awk '/will be expired/ { print $7 }')
21383         else
21384                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21385         fi
21386
21387         echo $expired
21388 }
21389
21390 test_801a() {
21391         prep_801
21392
21393         echo "Start barrier_freeze at: $(date)"
21394         #define OBD_FAIL_BARRIER_DELAY          0x2202
21395         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21396         # Do not reduce barrier time - See LU-11873
21397         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21398
21399         sleep 2
21400         local b_status=$(barrier_stat)
21401         echo "Got barrier status at: $(date)"
21402         [ "$b_status" = "'freezing_p1'" ] ||
21403                 error "(1) unexpected barrier status $b_status"
21404
21405         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21406         wait
21407         b_status=$(barrier_stat)
21408         [ "$b_status" = "'frozen'" ] ||
21409                 error "(2) unexpected barrier status $b_status"
21410
21411         local expired=$(barrier_expired)
21412         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21413         sleep $((expired + 3))
21414
21415         b_status=$(barrier_stat)
21416         [ "$b_status" = "'expired'" ] ||
21417                 error "(3) unexpected barrier status $b_status"
21418
21419         # Do not reduce barrier time - See LU-11873
21420         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21421                 error "(4) fail to freeze barrier"
21422
21423         b_status=$(barrier_stat)
21424         [ "$b_status" = "'frozen'" ] ||
21425                 error "(5) unexpected barrier status $b_status"
21426
21427         echo "Start barrier_thaw at: $(date)"
21428         #define OBD_FAIL_BARRIER_DELAY          0x2202
21429         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21430         do_facet mgs $LCTL barrier_thaw $FSNAME &
21431
21432         sleep 2
21433         b_status=$(barrier_stat)
21434         echo "Got barrier status at: $(date)"
21435         [ "$b_status" = "'thawing'" ] ||
21436                 error "(6) unexpected barrier status $b_status"
21437
21438         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21439         wait
21440         b_status=$(barrier_stat)
21441         [ "$b_status" = "'thawed'" ] ||
21442                 error "(7) unexpected barrier status $b_status"
21443
21444         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21445         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21446         do_facet mgs $LCTL barrier_freeze $FSNAME
21447
21448         b_status=$(barrier_stat)
21449         [ "$b_status" = "'failed'" ] ||
21450                 error "(8) unexpected barrier status $b_status"
21451
21452         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21453         do_facet mgs $LCTL barrier_thaw $FSNAME
21454
21455         post_801
21456 }
21457 run_test 801a "write barrier user interfaces and stat machine"
21458
21459 test_801b() {
21460         prep_801
21461
21462         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21463         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21464         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21465         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21466         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21467
21468         cancel_lru_locks mdc
21469
21470         # 180 seconds should be long enough
21471         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21472
21473         local b_status=$(barrier_stat)
21474         [ "$b_status" = "'frozen'" ] ||
21475                 error "(6) unexpected barrier status $b_status"
21476
21477         mkdir $DIR/$tdir/d0/d10 &
21478         mkdir_pid=$!
21479
21480         touch $DIR/$tdir/d1/f13 &
21481         touch_pid=$!
21482
21483         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21484         ln_pid=$!
21485
21486         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21487         mv_pid=$!
21488
21489         rm -f $DIR/$tdir/d4/f12 &
21490         rm_pid=$!
21491
21492         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21493
21494         # To guarantee taht the 'stat' is not blocked
21495         b_status=$(barrier_stat)
21496         [ "$b_status" = "'frozen'" ] ||
21497                 error "(8) unexpected barrier status $b_status"
21498
21499         # let above commands to run at background
21500         sleep 5
21501
21502         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21503         ps -p $touch_pid || error "(10) touch should be blocked"
21504         ps -p $ln_pid || error "(11) link should be blocked"
21505         ps -p $mv_pid || error "(12) rename should be blocked"
21506         ps -p $rm_pid || error "(13) unlink should be blocked"
21507
21508         b_status=$(barrier_stat)
21509         [ "$b_status" = "'frozen'" ] ||
21510                 error "(14) unexpected barrier status $b_status"
21511
21512         do_facet mgs $LCTL barrier_thaw $FSNAME
21513         b_status=$(barrier_stat)
21514         [ "$b_status" = "'thawed'" ] ||
21515                 error "(15) unexpected barrier status $b_status"
21516
21517         wait $mkdir_pid || error "(16) mkdir should succeed"
21518         wait $touch_pid || error "(17) touch should succeed"
21519         wait $ln_pid || error "(18) link should succeed"
21520         wait $mv_pid || error "(19) rename should succeed"
21521         wait $rm_pid || error "(20) unlink should succeed"
21522
21523         post_801
21524 }
21525 run_test 801b "modification will be blocked by write barrier"
21526
21527 test_801c() {
21528         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21529
21530         prep_801
21531
21532         stop mds2 || error "(1) Fail to stop mds2"
21533
21534         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21535
21536         local b_status=$(barrier_stat)
21537         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21538                 do_facet mgs $LCTL barrier_thaw $FSNAME
21539                 error "(2) unexpected barrier status $b_status"
21540         }
21541
21542         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21543                 error "(3) Fail to rescan barrier bitmap"
21544
21545         # Do not reduce barrier time - See LU-11873
21546         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21547
21548         b_status=$(barrier_stat)
21549         [ "$b_status" = "'frozen'" ] ||
21550                 error "(4) unexpected barrier status $b_status"
21551
21552         do_facet mgs $LCTL barrier_thaw $FSNAME
21553         b_status=$(barrier_stat)
21554         [ "$b_status" = "'thawed'" ] ||
21555                 error "(5) unexpected barrier status $b_status"
21556
21557         local devname=$(mdsdevname 2)
21558
21559         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21560
21561         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21562                 error "(7) Fail to rescan barrier bitmap"
21563
21564         post_801
21565 }
21566 run_test 801c "rescan barrier bitmap"
21567
21568 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21569 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21570 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21571 saved_MOUNT_OPTS=$MOUNT_OPTS
21572
21573 cleanup_802a() {
21574         trap 0
21575
21576         stopall
21577         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21578         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21579         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21580         MOUNT_OPTS=$saved_MOUNT_OPTS
21581         setupall
21582 }
21583
21584 test_802a() {
21585         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21586         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21587         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21588                 skip "Need server version at least 2.9.55"
21589
21590         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21591
21592         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21593
21594         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21595                 error "(2) Fail to copy"
21596
21597         trap cleanup_802a EXIT
21598
21599         # sync by force before remount as readonly
21600         sync; sync_all_data; sleep 3; sync_all_data
21601
21602         stopall
21603
21604         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21605         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21606         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21607
21608         echo "Mount the server as read only"
21609         setupall server_only || error "(3) Fail to start servers"
21610
21611         echo "Mount client without ro should fail"
21612         mount_client $MOUNT &&
21613                 error "(4) Mount client without 'ro' should fail"
21614
21615         echo "Mount client with ro should succeed"
21616         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21617         mount_client $MOUNT ||
21618                 error "(5) Mount client with 'ro' should succeed"
21619
21620         echo "Modify should be refused"
21621         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21622
21623         echo "Read should be allowed"
21624         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21625                 error "(7) Read should succeed under ro mode"
21626
21627         cleanup_802a
21628 }
21629 run_test 802a "simulate readonly device"
21630
21631 test_802b() {
21632         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21633         remote_mds_nodsh && skip "remote MDS with nodsh"
21634
21635         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21636                 skip "readonly option not available"
21637
21638         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21639
21640         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21641                 error "(2) Fail to copy"
21642
21643         # write back all cached data before setting MDT to readonly
21644         cancel_lru_locks
21645         sync_all_data
21646
21647         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21648         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21649
21650         echo "Modify should be refused"
21651         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21652
21653         echo "Read should be allowed"
21654         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21655                 error "(7) Read should succeed under ro mode"
21656
21657         # disable readonly
21658         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21659 }
21660 run_test 802b "be able to set MDTs to readonly"
21661
21662 test_803() {
21663         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21664         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21665                 skip "MDS needs to be newer than 2.10.54"
21666
21667         mkdir -p $DIR/$tdir
21668         # Create some objects on all MDTs to trigger related logs objects
21669         for idx in $(seq $MDSCOUNT); do
21670                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21671                         $DIR/$tdir/dir${idx} ||
21672                         error "Fail to create $DIR/$tdir/dir${idx}"
21673         done
21674
21675         sync; sleep 3
21676         wait_delete_completed # ensure old test cleanups are finished
21677         echo "before create:"
21678         $LFS df -i $MOUNT
21679         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21680
21681         for i in {1..10}; do
21682                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21683                         error "Fail to create $DIR/$tdir/foo$i"
21684         done
21685
21686         sync; sleep 3
21687         echo "after create:"
21688         $LFS df -i $MOUNT
21689         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21690
21691         # allow for an llog to be cleaned up during the test
21692         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21693                 error "before ($before_used) + 10 > after ($after_used)"
21694
21695         for i in {1..10}; do
21696                 rm -rf $DIR/$tdir/foo$i ||
21697                         error "Fail to remove $DIR/$tdir/foo$i"
21698         done
21699
21700         sleep 3 # avoid MDT return cached statfs
21701         wait_delete_completed
21702         echo "after unlink:"
21703         $LFS df -i $MOUNT
21704         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21705
21706         # allow for an llog to be created during the test
21707         [ $after_used -le $((before_used + 1)) ] ||
21708                 error "after ($after_used) > before ($before_used) + 1"
21709 }
21710 run_test 803 "verify agent object for remote object"
21711
21712 test_804() {
21713         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21714         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21715                 skip "MDS needs to be newer than 2.10.54"
21716         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21717
21718         mkdir -p $DIR/$tdir
21719         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21720                 error "Fail to create $DIR/$tdir/dir0"
21721
21722         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21723         local dev=$(mdsdevname 2)
21724
21725         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21726                 grep ${fid} || error "NOT found agent entry for dir0"
21727
21728         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21729                 error "Fail to create $DIR/$tdir/dir1"
21730
21731         touch $DIR/$tdir/dir1/foo0 ||
21732                 error "Fail to create $DIR/$tdir/dir1/foo0"
21733         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21734         local rc=0
21735
21736         for idx in $(seq $MDSCOUNT); do
21737                 dev=$(mdsdevname $idx)
21738                 do_facet mds${idx} \
21739                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21740                         grep ${fid} && rc=$idx
21741         done
21742
21743         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21744                 error "Fail to rename foo0 to foo1"
21745         if [ $rc -eq 0 ]; then
21746                 for idx in $(seq $MDSCOUNT); do
21747                         dev=$(mdsdevname $idx)
21748                         do_facet mds${idx} \
21749                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21750                         grep ${fid} && rc=$idx
21751                 done
21752         fi
21753
21754         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21755                 error "Fail to rename foo1 to foo2"
21756         if [ $rc -eq 0 ]; then
21757                 for idx in $(seq $MDSCOUNT); do
21758                         dev=$(mdsdevname $idx)
21759                         do_facet mds${idx} \
21760                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21761                         grep ${fid} && rc=$idx
21762                 done
21763         fi
21764
21765         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21766
21767         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21768                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21769         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21770                 error "Fail to rename foo2 to foo0"
21771         unlink $DIR/$tdir/dir1/foo0 ||
21772                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21773         rm -rf $DIR/$tdir/dir0 ||
21774                 error "Fail to rm $DIR/$tdir/dir0"
21775
21776         for idx in $(seq $MDSCOUNT); do
21777                 dev=$(mdsdevname $idx)
21778                 rc=0
21779
21780                 stop mds${idx}
21781                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21782                         rc=$?
21783                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21784                         error "mount mds$idx failed"
21785                 df $MOUNT > /dev/null 2>&1
21786
21787                 # e2fsck should not return error
21788                 [ $rc -eq 0 ] ||
21789                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21790         done
21791 }
21792 run_test 804 "verify agent entry for remote entry"
21793
21794 cleanup_805() {
21795         do_facet $SINGLEMDS zfs set quota=$old $fsset
21796         unlinkmany $DIR/$tdir/f- 1000000
21797         trap 0
21798 }
21799
21800 test_805() {
21801         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21802         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21803         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21804                 skip "netfree not implemented before 0.7"
21805         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21806                 skip "Need MDS version at least 2.10.57"
21807
21808         local fsset
21809         local freekb
21810         local usedkb
21811         local old
21812         local quota
21813         local pref="osd-zfs.lustre-MDT0000."
21814
21815         # limit available space on MDS dataset to meet nospace issue
21816         # quickly. then ZFS 0.7.2 can use reserved space if asked
21817         # properly (using netfree flag in osd_declare_destroy()
21818         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21819         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21820                 gawk '{print $3}')
21821         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21822         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21823         let "usedkb=usedkb-freekb"
21824         let "freekb=freekb/2"
21825         if let "freekb > 5000"; then
21826                 let "freekb=5000"
21827         fi
21828         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21829         trap cleanup_805 EXIT
21830         mkdir $DIR/$tdir
21831         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21832         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21833         rm -rf $DIR/$tdir || error "not able to remove"
21834         do_facet $SINGLEMDS zfs set quota=$old $fsset
21835         trap 0
21836 }
21837 run_test 805 "ZFS can remove from full fs"
21838
21839 # Size-on-MDS test
21840 check_lsom_data()
21841 {
21842         local file=$1
21843         local size=$($LFS getsom -s $file)
21844         local expect=$(stat -c %s $file)
21845
21846         [[ $size == $expect ]] ||
21847                 error "$file expected size: $expect, got: $size"
21848
21849         local blocks=$($LFS getsom -b $file)
21850         expect=$(stat -c %b $file)
21851         [[ $blocks == $expect ]] ||
21852                 error "$file expected blocks: $expect, got: $blocks"
21853 }
21854
21855 check_lsom_size()
21856 {
21857         local size=$($LFS getsom -s $1)
21858         local expect=$2
21859
21860         [[ $size == $expect ]] ||
21861                 error "$file expected size: $expect, got: $size"
21862 }
21863
21864 test_806() {
21865         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21866                 skip "Need MDS version at least 2.11.52"
21867
21868         local bs=1048576
21869
21870         touch $DIR/$tfile || error "touch $tfile failed"
21871
21872         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21873         save_lustre_params client "llite.*.xattr_cache" > $save
21874         lctl set_param llite.*.xattr_cache=0
21875         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21876
21877         # single-threaded write
21878         echo "Test SOM for single-threaded write"
21879         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21880                 error "write $tfile failed"
21881         check_lsom_size $DIR/$tfile $bs
21882
21883         local num=32
21884         local size=$(($num * $bs))
21885         local offset=0
21886         local i
21887
21888         echo "Test SOM for single client multi-threaded($num) write"
21889         $TRUNCATE $DIR/$tfile 0
21890         for ((i = 0; i < $num; i++)); do
21891                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21892                 local pids[$i]=$!
21893                 offset=$((offset + $bs))
21894         done
21895         for (( i=0; i < $num; i++ )); do
21896                 wait ${pids[$i]}
21897         done
21898         check_lsom_size $DIR/$tfile $size
21899
21900         $TRUNCATE $DIR/$tfile 0
21901         for ((i = 0; i < $num; i++)); do
21902                 offset=$((offset - $bs))
21903                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21904                 local pids[$i]=$!
21905         done
21906         for (( i=0; i < $num; i++ )); do
21907                 wait ${pids[$i]}
21908         done
21909         check_lsom_size $DIR/$tfile $size
21910
21911         # multi-client writes
21912         num=$(get_node_count ${CLIENTS//,/ })
21913         size=$(($num * $bs))
21914         offset=0
21915         i=0
21916
21917         echo "Test SOM for multi-client ($num) writes"
21918         $TRUNCATE $DIR/$tfile 0
21919         for client in ${CLIENTS//,/ }; do
21920                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21921                 local pids[$i]=$!
21922                 i=$((i + 1))
21923                 offset=$((offset + $bs))
21924         done
21925         for (( i=0; i < $num; i++ )); do
21926                 wait ${pids[$i]}
21927         done
21928         check_lsom_size $DIR/$tfile $offset
21929
21930         i=0
21931         $TRUNCATE $DIR/$tfile 0
21932         for client in ${CLIENTS//,/ }; do
21933                 offset=$((offset - $bs))
21934                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21935                 local pids[$i]=$!
21936                 i=$((i + 1))
21937         done
21938         for (( i=0; i < $num; i++ )); do
21939                 wait ${pids[$i]}
21940         done
21941         check_lsom_size $DIR/$tfile $size
21942
21943         # verify truncate
21944         echo "Test SOM for truncate"
21945         $TRUNCATE $DIR/$tfile 1048576
21946         check_lsom_size $DIR/$tfile 1048576
21947         $TRUNCATE $DIR/$tfile 1234
21948         check_lsom_size $DIR/$tfile 1234
21949
21950         # verify SOM blocks count
21951         echo "Verify SOM block count"
21952         $TRUNCATE $DIR/$tfile 0
21953         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21954                 error "failed to write file $tfile"
21955         check_lsom_data $DIR/$tfile
21956 }
21957 run_test 806 "Verify Lazy Size on MDS"
21958
21959 test_807() {
21960         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21961         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21962                 skip "Need MDS version at least 2.11.52"
21963
21964         # Registration step
21965         changelog_register || error "changelog_register failed"
21966         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21967         changelog_users $SINGLEMDS | grep -q $cl_user ||
21968                 error "User $cl_user not found in changelog_users"
21969
21970         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21971         save_lustre_params client "llite.*.xattr_cache" > $save
21972         lctl set_param llite.*.xattr_cache=0
21973         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21974
21975         rm -rf $DIR/$tdir || error "rm $tdir failed"
21976         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21977         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21978         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21979         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21980                 error "truncate $tdir/trunc failed"
21981
21982         local bs=1048576
21983         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21984                 error "write $tfile failed"
21985
21986         # multi-client wirtes
21987         local num=$(get_node_count ${CLIENTS//,/ })
21988         local offset=0
21989         local i=0
21990
21991         echo "Test SOM for multi-client ($num) writes"
21992         touch $DIR/$tfile || error "touch $tfile failed"
21993         $TRUNCATE $DIR/$tfile 0
21994         for client in ${CLIENTS//,/ }; do
21995                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21996                 local pids[$i]=$!
21997                 i=$((i + 1))
21998                 offset=$((offset + $bs))
21999         done
22000         for (( i=0; i < $num; i++ )); do
22001                 wait ${pids[$i]}
22002         done
22003
22004         sleep 5
22005         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
22006         check_lsom_data $DIR/$tdir/trunc
22007         check_lsom_data $DIR/$tdir/single_dd
22008         check_lsom_data $DIR/$tfile
22009
22010         rm -rf $DIR/$tdir
22011         # Deregistration step
22012         changelog_deregister || error "changelog_deregister failed"
22013 }
22014 run_test 807 "verify LSOM syncing tool"
22015
22016 check_som_nologged()
22017 {
22018         local lines=$($LFS changelog $FSNAME-MDT0000 |
22019                 grep 'x=trusted.som' | wc -l)
22020         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
22021 }
22022
22023 test_808() {
22024         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
22025                 skip "Need MDS version at least 2.11.55"
22026
22027         # Registration step
22028         changelog_register || error "changelog_register failed"
22029
22030         touch $DIR/$tfile || error "touch $tfile failed"
22031         check_som_nologged
22032
22033         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
22034                 error "write $tfile failed"
22035         check_som_nologged
22036
22037         $TRUNCATE $DIR/$tfile 1234
22038         check_som_nologged
22039
22040         $TRUNCATE $DIR/$tfile 1048576
22041         check_som_nologged
22042
22043         # Deregistration step
22044         changelog_deregister || error "changelog_deregister failed"
22045 }
22046 run_test 808 "Check trusted.som xattr not logged in Changelogs"
22047
22048 check_som_nodata()
22049 {
22050         $LFS getsom $1
22051         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
22052 }
22053
22054 test_809() {
22055         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
22056                 skip "Need MDS version at least 2.11.56"
22057
22058         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
22059                 error "failed to create DoM-only file $DIR/$tfile"
22060         touch $DIR/$tfile || error "touch $tfile failed"
22061         check_som_nodata $DIR/$tfile
22062
22063         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
22064                 error "write $tfile failed"
22065         check_som_nodata $DIR/$tfile
22066
22067         $TRUNCATE $DIR/$tfile 1234
22068         check_som_nodata $DIR/$tfile
22069
22070         $TRUNCATE $DIR/$tfile 4097
22071         check_som_nodata $DIR/$file
22072 }
22073 run_test 809 "Verify no SOM xattr store for DoM-only files"
22074
22075 test_810() {
22076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22077         $GSS && skip_env "could not run with gss"
22078
22079         set_checksums 1
22080         stack_trap "set_checksums $ORIG_CSUM" EXIT
22081         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
22082
22083         local csum
22084         local before
22085         local after
22086         for csum in $CKSUM_TYPES; do
22087                 #define OBD_FAIL_OSC_NO_GRANT   0x411
22088                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
22089                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
22090                         eval set -- $i
22091                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
22092                         before=$(md5sum $DIR/$tfile)
22093                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
22094                         after=$(md5sum $DIR/$tfile)
22095                         [ "$before" == "$after" ] ||
22096                                 error "$csum: $before != $after bs=$1 seek=$2"
22097                 done
22098         done
22099 }
22100 run_test 810 "partial page writes on ZFS (LU-11663)"
22101
22102 test_811() {
22103         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
22104                 skip "Need MDS version at least 2.11.56"
22105
22106         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
22107         do_facet mds1 $LCTL set_param fail_loc=0x165
22108         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
22109
22110         stop mds1
22111         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
22112
22113         sleep 5
22114         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
22115                 error "MDD orphan cleanup thread not quit"
22116 }
22117 run_test 811 "orphan name stub can be cleaned up in startup"
22118
22119 test_812() {
22120         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
22121                 skip "OST < 2.12.51 doesn't support this fail_loc"
22122         [ "$SHARED_KEY" = true ] &&
22123                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22124
22125         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22126         # ensure ost1 is connected
22127         stat $DIR/$tfile >/dev/null || error "can't stat"
22128         wait_osc_import_state client ost1 FULL
22129         # no locks, no reqs to let the connection idle
22130         cancel_lru_locks osc
22131
22132         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
22133 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
22134         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
22135         wait_osc_import_state client ost1 CONNECTING
22136         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
22137
22138         stat $DIR/$tfile >/dev/null || error "can't stat file"
22139 }
22140 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
22141
22142 test_813() {
22143         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
22144         [ -z "$file_heat_sav" ] && skip "no file heat support"
22145
22146         local readsample
22147         local writesample
22148         local readbyte
22149         local writebyte
22150         local readsample1
22151         local writesample1
22152         local readbyte1
22153         local writebyte1
22154
22155         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
22156         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
22157
22158         $LCTL set_param -n llite.*.file_heat=1
22159         echo "Turn on file heat"
22160         echo "Period second: $period_second, Decay percentage: $decay_pct"
22161
22162         echo "QQQQ" > $DIR/$tfile
22163         echo "QQQQ" > $DIR/$tfile
22164         echo "QQQQ" > $DIR/$tfile
22165         cat $DIR/$tfile > /dev/null
22166         cat $DIR/$tfile > /dev/null
22167         cat $DIR/$tfile > /dev/null
22168         cat $DIR/$tfile > /dev/null
22169
22170         local out=$($LFS heat_get $DIR/$tfile)
22171
22172         $LFS heat_get $DIR/$tfile
22173         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22174         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22175         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22176         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22177
22178         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
22179         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
22180         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
22181         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
22182
22183         sleep $((period_second + 3))
22184         echo "Sleep $((period_second + 3)) seconds..."
22185         # The recursion formula to calculate the heat of the file f is as
22186         # follow:
22187         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
22188         # Where Hi is the heat value in the period between time points i*I and
22189         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22190         # to the weight of Ci.
22191         out=$($LFS heat_get $DIR/$tfile)
22192         $LFS heat_get $DIR/$tfile
22193         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22194         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22195         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22196         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22197
22198         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22199                 error "read sample ($readsample) is wrong"
22200         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22201                 error "write sample ($writesample) is wrong"
22202         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22203                 error "read bytes ($readbyte) is wrong"
22204         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22205                 error "write bytes ($writebyte) is wrong"
22206
22207         echo "QQQQ" > $DIR/$tfile
22208         echo "QQQQ" > $DIR/$tfile
22209         echo "QQQQ" > $DIR/$tfile
22210         cat $DIR/$tfile > /dev/null
22211         cat $DIR/$tfile > /dev/null
22212         cat $DIR/$tfile > /dev/null
22213         cat $DIR/$tfile > /dev/null
22214
22215         sleep $((period_second + 3))
22216         echo "Sleep $((period_second + 3)) seconds..."
22217
22218         out=$($LFS heat_get $DIR/$tfile)
22219         $LFS heat_get $DIR/$tfile
22220         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22221         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22222         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22223         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22224
22225         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22226                 4 * $decay_pct) / 100") -eq 1 ] ||
22227                 error "read sample ($readsample1) is wrong"
22228         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22229                 3 * $decay_pct) / 100") -eq 1 ] ||
22230                 error "write sample ($writesample1) is wrong"
22231         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22232                 20 * $decay_pct) / 100") -eq 1 ] ||
22233                 error "read bytes ($readbyte1) is wrong"
22234         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22235                 15 * $decay_pct) / 100") -eq 1 ] ||
22236                 error "write bytes ($writebyte1) is wrong"
22237
22238         echo "Turn off file heat for the file $DIR/$tfile"
22239         $LFS heat_set -o $DIR/$tfile
22240
22241         echo "QQQQ" > $DIR/$tfile
22242         echo "QQQQ" > $DIR/$tfile
22243         echo "QQQQ" > $DIR/$tfile
22244         cat $DIR/$tfile > /dev/null
22245         cat $DIR/$tfile > /dev/null
22246         cat $DIR/$tfile > /dev/null
22247         cat $DIR/$tfile > /dev/null
22248
22249         out=$($LFS heat_get $DIR/$tfile)
22250         $LFS heat_get $DIR/$tfile
22251         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22252         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22253         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22254         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22255
22256         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22257         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22258         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22259         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22260
22261         echo "Trun on file heat for the file $DIR/$tfile"
22262         $LFS heat_set -O $DIR/$tfile
22263
22264         echo "QQQQ" > $DIR/$tfile
22265         echo "QQQQ" > $DIR/$tfile
22266         echo "QQQQ" > $DIR/$tfile
22267         cat $DIR/$tfile > /dev/null
22268         cat $DIR/$tfile > /dev/null
22269         cat $DIR/$tfile > /dev/null
22270         cat $DIR/$tfile > /dev/null
22271
22272         out=$($LFS heat_get $DIR/$tfile)
22273         $LFS heat_get $DIR/$tfile
22274         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22275         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22276         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22277         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22278
22279         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22280         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22281         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22282         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22283
22284         $LFS heat_set -c $DIR/$tfile
22285         $LCTL set_param -n llite.*.file_heat=0
22286         echo "Turn off file heat support for the Lustre filesystem"
22287
22288         echo "QQQQ" > $DIR/$tfile
22289         echo "QQQQ" > $DIR/$tfile
22290         echo "QQQQ" > $DIR/$tfile
22291         cat $DIR/$tfile > /dev/null
22292         cat $DIR/$tfile > /dev/null
22293         cat $DIR/$tfile > /dev/null
22294         cat $DIR/$tfile > /dev/null
22295
22296         out=$($LFS heat_get $DIR/$tfile)
22297         $LFS heat_get $DIR/$tfile
22298         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22299         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22300         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22301         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22302
22303         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22304         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22305         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22306         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22307
22308         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22309         rm -f $DIR/$tfile
22310 }
22311 run_test 813 "File heat verfication"
22312
22313 test_814()
22314 {
22315         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22316         echo -n y >> $DIR/$tfile
22317         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22318         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22319 }
22320 run_test 814 "sparse cp works as expected (LU-12361)"
22321
22322 test_815()
22323 {
22324         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22325         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22326 }
22327 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22328
22329 test_816() {
22330         [ "$SHARED_KEY" = true ] &&
22331                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22332
22333         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22334         # ensure ost1 is connected
22335         stat $DIR/$tfile >/dev/null || error "can't stat"
22336         wait_osc_import_state client ost1 FULL
22337         # no locks, no reqs to let the connection idle
22338         cancel_lru_locks osc
22339         lru_resize_disable osc
22340         local before
22341         local now
22342         before=$($LCTL get_param -n \
22343                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22344
22345         wait_osc_import_state client ost1 IDLE
22346         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22347         now=$($LCTL get_param -n \
22348               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22349         [ $before == $now ] || error "lru_size changed $before != $now"
22350 }
22351 run_test 816 "do not reset lru_resize on idle reconnect"
22352
22353 cleanup_817() {
22354         umount $tmpdir
22355         exportfs -u localhost:$DIR/nfsexp
22356         rm -rf $DIR/nfsexp
22357 }
22358
22359 test_817() {
22360         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22361
22362         mkdir -p $DIR/nfsexp
22363         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22364                 error "failed to export nfs"
22365
22366         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22367         stack_trap cleanup_817 EXIT
22368
22369         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22370                 error "failed to mount nfs to $tmpdir"
22371
22372         cp /bin/true $tmpdir
22373         $DIR/nfsexp/true || error "failed to execute 'true' command"
22374 }
22375 run_test 817 "nfsd won't cache write lock for exec file"
22376
22377 test_818() {
22378         mkdir $DIR/$tdir
22379         $LFS setstripe -c1 -i0 $DIR/$tfile
22380         $LFS setstripe -c1 -i1 $DIR/$tfile
22381         stop $SINGLEMDS
22382         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22383         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22384         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22385                 error "start $SINGLEMDS failed"
22386         rm -rf $DIR/$tdir
22387 }
22388 run_test 818 "unlink with failed llog"
22389
22390 test_819a() {
22391         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22392         cancel_lru_locks osc
22393         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22394         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22395         dd if=$DIR/$tfile of=/dev/null bs=1M count=1
22396         rm -f $TDIR/$tfile
22397 }
22398 run_test 819a "too big niobuf in read"
22399
22400 test_819b() {
22401         #define OBD_FAIL_OST_2BIG_NIOBUF                0x248
22402         do_facet $SINGLEMDS lctl set_param fail_loc=0x80000248
22403         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
22404         cancel_lru_locks osc
22405         sleep 1
22406         rm -f $TDIR/$tfile
22407 }
22408 run_test 819b "too big niobuf in write"
22409
22410 #
22411 # tests that do cleanup/setup should be run at the end
22412 #
22413
22414 test_900() {
22415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22416         local ls
22417
22418         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22419         $LCTL set_param fail_loc=0x903
22420
22421         cancel_lru_locks MGC
22422
22423         FAIL_ON_ERROR=true cleanup
22424         FAIL_ON_ERROR=true setup
22425 }
22426 run_test 900 "umount should not race with any mgc requeue thread"
22427
22428 complete $SECONDS
22429 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22430 check_and_cleanup_lustre
22431 if [ "$I_MOUNTED" != "yes" ]; then
22432         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22433 fi
22434 exit_status