Whamcloud - gitweb
LU-12622 tests: skip sanity test_816 with SSK
[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-11729 LU-4398
57         ALWAYS_EXCEPT+=" 45       317      810       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: LU-1957
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # 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         if ! combined_mgs_mds ; then
2462                 mount_mgs_client
2463         fi
2464
2465         test_mkdir $DIR/$tdir
2466         pool_add $POOL || error "pool_add failed"
2467         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2468
2469         local skip27D
2470         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2471                 skip27D+="-s 29"
2472         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2473                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2474                         skip27D+=" -s 30,31"
2475         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2476                 skip27D+="-s 32"
2477         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2478           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2479                 skip27D+=" -s 32,33"
2480         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2481                 error "llapi_layout_test failed"
2482
2483         destroy_test_pools || error "destroy test pools failed"
2484
2485         if ! combined_mgs_mds ; then
2486                 umount_mgs_client
2487         fi
2488 }
2489 run_test 27D "validate llapi_layout API"
2490
2491 # Verify that default_easize is increased from its initial value after
2492 # accessing a widely striped file.
2493 test_27E() {
2494         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2495         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2496                 skip "client does not have LU-3338 fix"
2497
2498         # 72 bytes is the minimum space required to store striping
2499         # information for a file striped across one OST:
2500         # (sizeof(struct lov_user_md_v3) +
2501         #  sizeof(struct lov_user_ost_data_v1))
2502         local min_easize=72
2503         $LCTL set_param -n llite.*.default_easize $min_easize ||
2504                 error "lctl set_param failed"
2505         local easize=$($LCTL get_param -n llite.*.default_easize)
2506
2507         [ $easize -eq $min_easize ] ||
2508                 error "failed to set default_easize"
2509
2510         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2511                 error "setstripe failed"
2512         # In order to ensure stat() call actually talks to MDS we need to
2513         # do something drastic to this file to shake off all lock, e.g.
2514         # rename it (kills lookup lock forcing cache cleaning)
2515         mv $DIR/$tfile $DIR/${tfile}-1
2516         ls -l $DIR/${tfile}-1
2517         rm $DIR/${tfile}-1
2518
2519         easize=$($LCTL get_param -n llite.*.default_easize)
2520
2521         [ $easize -gt $min_easize ] ||
2522                 error "default_easize not updated"
2523 }
2524 run_test 27E "check that default extended attribute size properly increases"
2525
2526 test_27F() { # LU-5346/LU-7975
2527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2528         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2529         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2530                 skip "Need MDS version at least 2.8.51"
2531         remote_ost_nodsh && skip "remote OST with nodsh"
2532
2533         test_mkdir $DIR/$tdir
2534         rm -f $DIR/$tdir/f0
2535         $LFS setstripe -c 2 $DIR/$tdir
2536
2537         # stop all OSTs to reproduce situation for LU-7975 ticket
2538         for num in $(seq $OSTCOUNT); do
2539                 stop ost$num
2540         done
2541
2542         # open/create f0 with O_LOV_DELAY_CREATE
2543         # truncate f0 to a non-0 size
2544         # close
2545         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2546
2547         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2548         # open/write it again to force delayed layout creation
2549         cat /etc/hosts > $DIR/$tdir/f0 &
2550         catpid=$!
2551
2552         # restart OSTs
2553         for num in $(seq $OSTCOUNT); do
2554                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2555                         error "ost$num failed to start"
2556         done
2557
2558         wait $catpid || error "cat failed"
2559
2560         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2561         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2562                 error "wrong stripecount"
2563
2564 }
2565 run_test 27F "Client resend delayed layout creation with non-zero size"
2566
2567 test_27G() { #LU-10629
2568         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2569                 skip "Need MDS version at least 2.11.51"
2570         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2571         remote_mds_nodsh && skip "remote MDS with nodsh"
2572         local POOL=${POOL:-testpool}
2573         local ostrange="0 0 1"
2574
2575         test_mkdir $DIR/$tdir
2576         pool_add $POOL || error "pool_add failed"
2577         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2578         $LFS setstripe -p $POOL $DIR/$tdir
2579
2580         local pool=$($LFS getstripe -p $DIR/$tdir)
2581
2582         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2583
2584         $LFS setstripe -d $DIR/$tdir
2585
2586         pool=$($LFS getstripe -p $DIR/$tdir)
2587
2588         rmdir $DIR/$tdir
2589
2590         [ -z "$pool" ] || error "'$pool' is not empty"
2591 }
2592 run_test 27G "Clear OST pool from stripe"
2593
2594 test_27H() {
2595         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2596                 skip "Need MDS version newer than 2.11.54"
2597         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2598         test_mkdir $DIR/$tdir
2599         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2600         touch $DIR/$tdir/$tfile
2601         $LFS getstripe -c $DIR/$tdir/$tfile
2602         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2603                 error "two-stripe file doesn't have two stripes"
2604
2605         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2606         $LFS getstripe -y $DIR/$tdir/$tfile
2607         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2608              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2609                 error "expected l_ost_idx: [02]$ not matched"
2610
2611         # make sure ost list has been cleared
2612         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2613         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2614                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2615         touch $DIR/$tdir/f3
2616         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2617 }
2618 run_test 27H "Set specific OSTs stripe"
2619
2620 test_27I() {
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2623         local pool=$TESTNAME
2624         local ostrange="1 1 1"
2625
2626         save_layout_restore_at_exit $MOUNT
2627         $LFS setstripe -c 2 -i 0 $MOUNT
2628         pool_add $pool || error "pool_add failed"
2629         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2630         test_mkdir $DIR/$tdir
2631         $LFS setstripe -p $pool $DIR/$tdir
2632         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2633         $LFS getstripe $DIR/$tdir/$tfile
2634 }
2635 run_test 27I "check that root dir striping does not break parent dir one"
2636
2637 test_27J() {
2638         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2639                 skip "Need MDS version newer than 2.12.51"
2640
2641         test_mkdir $DIR/$tdir
2642         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2643         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2644
2645         # create foreign file (raw way)
2646         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2647                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2648
2649         # verify foreign file (raw way)
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2653         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2654                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2655         parse_foreign_file -f $DIR/$tdir/$tfile |
2656                 grep "lov_foreign_size: 73" ||
2657                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2658         parse_foreign_file -f $DIR/$tdir/$tfile |
2659                 grep "lov_foreign_type: 1" ||
2660                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2661         parse_foreign_file -f $DIR/$tdir/$tfile |
2662                 grep "lov_foreign_flags: 0x0000DA08" ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2664         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2665                 grep "lov_foreign_value: 0x" |
2666                 sed -e 's/lov_foreign_value: 0x//')
2667         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2668         [[ $lov = ${lov2// /} ]] ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2670
2671         # create foreign file (lfs + API)
2672         $LFS setstripe --foreign=daos --flags 0xda08 \
2673                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2674                 error "$DIR/$tdir/${tfile}2: create failed"
2675
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_magic:.*0x0BD70BD0" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2679         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2683                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2684         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2685                 grep "lfm_flags:.*0x0000DA08" ||
2686                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2687         $LFS getstripe $DIR/$tdir/${tfile}2 |
2688                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2689                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2690
2691         # modify striping should fail
2692         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2693                 error "$DIR/$tdir/$tfile: setstripe should fail"
2694         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2695                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2696
2697         # R/W should fail
2698         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2699         cat $DIR/$tdir/${tfile}2 &&
2700                 error "$DIR/$tdir/${tfile}2: read should fail"
2701         cat /etc/passwd > $DIR/$tdir/$tfile &&
2702                 error "$DIR/$tdir/$tfile: write should fail"
2703         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2704                 error "$DIR/$tdir/${tfile}2: write should fail"
2705
2706         # chmod should work
2707         chmod 222 $DIR/$tdir/$tfile ||
2708                 error "$DIR/$tdir/$tfile: chmod failed"
2709         chmod 222 $DIR/$tdir/${tfile}2 ||
2710                 error "$DIR/$tdir/${tfile}2: chmod failed"
2711
2712         # chown should work
2713         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2714                 error "$DIR/$tdir/$tfile: chown failed"
2715         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2716                 error "$DIR/$tdir/${tfile}2: chown failed"
2717
2718         # rename should work
2719         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2720                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2721         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2722                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2723
2724         #remove foreign file
2725         rm $DIR/$tdir/${tfile}.new ||
2726                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2727         rm $DIR/$tdir/${tfile}2.new ||
2728                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2729 }
2730 run_test 27J "basic ops on file with foreign LOV"
2731
2732 test_27K() {
2733         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2734                 skip "Need MDS version newer than 2.12.49"
2735
2736         test_mkdir $DIR/$tdir
2737         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2738         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2739
2740         # create foreign dir (raw way)
2741         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2742                 error "create_foreign_dir FAILED"
2743
2744         # verify foreign dir (raw way)
2745         parse_foreign_dir -d $DIR/$tdir/$tdir |
2746                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2747                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2748         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2749                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2750         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2751                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2752         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2753                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2754         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2755                 grep "lmv_foreign_value: 0x" |
2756                 sed 's/lmv_foreign_value: 0x//')
2757         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2758                 sed 's/ //g')
2759         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2760
2761         # create foreign dir (lfs + API)
2762         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2763                 $DIR/$tdir/${tdir}2 ||
2764                 error "$DIR/$tdir/${tdir}2: create failed"
2765
2766         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2767                 grep "lfm_magic:.*0x0CD50CD0" ||
2768                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2769         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2770         # - sizeof(lfm_type) - sizeof(lfm_flags)
2771         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2775         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2776                 grep "lfm_flags:.*0x0000DA05" ||
2777                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2778         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2779                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2781
2782         # file create in dir should fail
2783         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2784         touch $DIR/$tdir/${tdir}2/$tfile &&
2785                 "$DIR/${tdir}2: file create should fail"
2786
2787         # chmod should work
2788         chmod 777 $DIR/$tdir/$tdir ||
2789                 error "$DIR/$tdir: chmod failed"
2790         chmod 777 $DIR/$tdir/${tdir}2 ||
2791                 error "$DIR/${tdir}2: chmod failed"
2792
2793         # chown should work
2794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2795                 error "$DIR/$tdir: chown failed"
2796         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2797                 error "$DIR/${tdir}2: chown failed"
2798
2799         # rename should work
2800         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2801                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2802         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2803                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2804
2805         #remove foreign dir
2806         rmdir $DIR/$tdir/${tdir}.new ||
2807                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2808         rmdir $DIR/$tdir/${tdir}2.new ||
2809                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2810 }
2811 run_test 27K "basic ops on dir with foreign LMV"
2812
2813 test_27L() {
2814         remote_mds_nodsh && skip "remote MDS with nodsh"
2815
2816         local POOL=${POOL:-$TESTNAME}
2817
2818         if ! combined_mgs_mds ; then
2819                 mount_mgs_client
2820                 trap umount_mgs_client EXIT
2821         fi
2822
2823         pool_add $POOL || error "pool_add failed"
2824
2825         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2826                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2827                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2828 }
2829 run_test 27L "lfs pool_list gives correct pool name"
2830
2831 # createtest also checks that device nodes are created and
2832 # then visible correctly (#2091)
2833 test_28() { # bug 2091
2834         test_mkdir $DIR/d28
2835         $CREATETEST $DIR/d28/ct || error "createtest failed"
2836 }
2837 run_test 28 "create/mknod/mkdir with bad file types ============"
2838
2839 test_29() {
2840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2841
2842         sync; sleep 1; sync # flush out any dirty pages from previous tests
2843         cancel_lru_locks
2844         test_mkdir $DIR/d29
2845         touch $DIR/d29/foo
2846         log 'first d29'
2847         ls -l $DIR/d29
2848
2849         declare -i LOCKCOUNTORIG=0
2850         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2851                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2852         done
2853         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2854
2855         declare -i LOCKUNUSEDCOUNTORIG=0
2856         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2857                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2858         done
2859
2860         log 'second d29'
2861         ls -l $DIR/d29
2862         log 'done'
2863
2864         declare -i LOCKCOUNTCURRENT=0
2865         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2866                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2867         done
2868
2869         declare -i LOCKUNUSEDCOUNTCURRENT=0
2870         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2871                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2872         done
2873
2874         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2875                 $LCTL set_param -n ldlm.dump_namespaces ""
2876                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2877                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2878                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2879                 return 2
2880         fi
2881         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2882                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2883                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2884                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2885                 return 3
2886         fi
2887 }
2888 run_test 29 "IT_GETATTR regression  ============================"
2889
2890 test_30a() { # was test_30
2891         cp $(which ls) $DIR || cp /bin/ls $DIR
2892         $DIR/ls / || error "Can't execute binary from lustre"
2893         rm $DIR/ls
2894 }
2895 run_test 30a "execute binary from Lustre (execve) =============="
2896
2897 test_30b() {
2898         cp `which ls` $DIR || cp /bin/ls $DIR
2899         chmod go+rx $DIR/ls
2900         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2901         rm $DIR/ls
2902 }
2903 run_test 30b "execute binary from Lustre as non-root ==========="
2904
2905 test_30c() { # b=22376
2906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2907
2908         cp `which ls` $DIR || cp /bin/ls $DIR
2909         chmod a-rw $DIR/ls
2910         cancel_lru_locks mdc
2911         cancel_lru_locks osc
2912         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2913         rm -f $DIR/ls
2914 }
2915 run_test 30c "execute binary from Lustre without read perms ===="
2916
2917 test_31a() {
2918         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2919         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2920 }
2921 run_test 31a "open-unlink file =================================="
2922
2923 test_31b() {
2924         touch $DIR/f31 || error "touch $DIR/f31 failed"
2925         ln $DIR/f31 $DIR/f31b || error "ln failed"
2926         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2927         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2928 }
2929 run_test 31b "unlink file with multiple links while open ======="
2930
2931 test_31c() {
2932         touch $DIR/f31 || error "touch $DIR/f31 failed"
2933         ln $DIR/f31 $DIR/f31c || error "ln failed"
2934         multiop_bg_pause $DIR/f31 O_uc ||
2935                 error "multiop_bg_pause for $DIR/f31 failed"
2936         MULTIPID=$!
2937         $MULTIOP $DIR/f31c Ouc
2938         kill -USR1 $MULTIPID
2939         wait $MULTIPID
2940 }
2941 run_test 31c "open-unlink file with multiple links ============="
2942
2943 test_31d() {
2944         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2945         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2946 }
2947 run_test 31d "remove of open directory ========================="
2948
2949 test_31e() { # bug 2904
2950         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2951 }
2952 run_test 31e "remove of open non-empty directory ==============="
2953
2954 test_31f() { # bug 4554
2955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2956
2957         set -vx
2958         test_mkdir $DIR/d31f
2959         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2960         cp /etc/hosts $DIR/d31f
2961         ls -l $DIR/d31f
2962         $LFS getstripe $DIR/d31f/hosts
2963         multiop_bg_pause $DIR/d31f D_c || return 1
2964         MULTIPID=$!
2965
2966         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2967         test_mkdir $DIR/d31f
2968         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2969         cp /etc/hosts $DIR/d31f
2970         ls -l $DIR/d31f
2971         $LFS getstripe $DIR/d31f/hosts
2972         multiop_bg_pause $DIR/d31f D_c || return 1
2973         MULTIPID2=$!
2974
2975         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2976         wait $MULTIPID || error "first opendir $MULTIPID failed"
2977
2978         sleep 6
2979
2980         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2981         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2982         set +vx
2983 }
2984 run_test 31f "remove of open directory with open-unlink file ==="
2985
2986 test_31g() {
2987         echo "-- cross directory link --"
2988         test_mkdir -c1 $DIR/${tdir}ga
2989         test_mkdir -c1 $DIR/${tdir}gb
2990         touch $DIR/${tdir}ga/f
2991         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2992         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2993         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2994         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2995         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2996 }
2997 run_test 31g "cross directory link==============="
2998
2999 test_31h() {
3000         echo "-- cross directory link --"
3001         test_mkdir -c1 $DIR/${tdir}
3002         test_mkdir -c1 $DIR/${tdir}/dir
3003         touch $DIR/${tdir}/f
3004         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3005         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3006         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3007         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3008         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3009 }
3010 run_test 31h "cross directory link under child==============="
3011
3012 test_31i() {
3013         echo "-- cross directory link --"
3014         test_mkdir -c1 $DIR/$tdir
3015         test_mkdir -c1 $DIR/$tdir/dir
3016         touch $DIR/$tdir/dir/f
3017         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3018         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3019         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3020         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3021         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3022 }
3023 run_test 31i "cross directory link under parent==============="
3024
3025 test_31j() {
3026         test_mkdir -c1 -p $DIR/$tdir
3027         test_mkdir -c1 -p $DIR/$tdir/dir1
3028         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3029         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3030         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3031         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3032         return 0
3033 }
3034 run_test 31j "link for directory==============="
3035
3036 test_31k() {
3037         test_mkdir -c1 -p $DIR/$tdir
3038         touch $DIR/$tdir/s
3039         touch $DIR/$tdir/exist
3040         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3041         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3042         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3043         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3044         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3045         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3046         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3047         return 0
3048 }
3049 run_test 31k "link to file: the same, non-existing, dir==============="
3050
3051 test_31m() {
3052         mkdir $DIR/d31m
3053         touch $DIR/d31m/s
3054         mkdir $DIR/d31m2
3055         touch $DIR/d31m2/exist
3056         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3057         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3058         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3059         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3060         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3061         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3062         return 0
3063 }
3064 run_test 31m "link to file: the same, non-existing, dir==============="
3065
3066 test_31n() {
3067         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3068         nlink=$(stat --format=%h $DIR/$tfile)
3069         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3070         local fd=$(free_fd)
3071         local cmd="exec $fd<$DIR/$tfile"
3072         eval $cmd
3073         cmd="exec $fd<&-"
3074         trap "eval $cmd" EXIT
3075         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3076         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3077         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3078         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3079         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3080         eval $cmd
3081 }
3082 run_test 31n "check link count of unlinked file"
3083
3084 link_one() {
3085         local tempfile=$(mktemp $1_XXXXXX)
3086         mlink $tempfile $1 2> /dev/null &&
3087                 echo "$BASHPID: link $tempfile to $1 succeeded"
3088         munlink $tempfile
3089 }
3090
3091 test_31o() { # LU-2901
3092         test_mkdir $DIR/$tdir
3093         for LOOP in $(seq 100); do
3094                 rm -f $DIR/$tdir/$tfile*
3095                 for THREAD in $(seq 8); do
3096                         link_one $DIR/$tdir/$tfile.$LOOP &
3097                 done
3098                 wait
3099                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3100                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3101                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3102                         break || true
3103         done
3104 }
3105 run_test 31o "duplicate hard links with same filename"
3106
3107 test_31p() {
3108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3109
3110         test_mkdir $DIR/$tdir
3111         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3112         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3113
3114         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3115                 error "open unlink test1 failed"
3116         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3117                 error "open unlink test2 failed"
3118
3119         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3120                 error "test1 still exists"
3121         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3122                 error "test2 still exists"
3123 }
3124 run_test 31p "remove of open striped directory"
3125
3126 cleanup_test32_mount() {
3127         local rc=0
3128         trap 0
3129         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3130         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3131         losetup -d $loopdev || true
3132         rm -rf $DIR/$tdir
3133         return $rc
3134 }
3135
3136 test_32a() {
3137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3138
3139         echo "== more mountpoints and symlinks ================="
3140         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3141         trap cleanup_test32_mount EXIT
3142         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3145         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3146                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3147         cleanup_test32_mount
3148 }
3149 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3150
3151 test_32b() {
3152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3153
3154         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3155         trap cleanup_test32_mount EXIT
3156         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3159         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3160                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3161         cleanup_test32_mount
3162 }
3163 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3164
3165 test_32c() {
3166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3167
3168         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3169         trap cleanup_test32_mount EXIT
3170         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3171         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3172                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3173         test_mkdir -p $DIR/$tdir/d2/test_dir
3174         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3175                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3176         cleanup_test32_mount
3177 }
3178 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3179
3180 test_32d() {
3181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3182
3183         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3184         trap cleanup_test32_mount EXIT
3185         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3186         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3187                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3188         test_mkdir -p $DIR/$tdir/d2/test_dir
3189         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3190                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3191         cleanup_test32_mount
3192 }
3193 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3194
3195 test_32e() {
3196         rm -fr $DIR/$tdir
3197         test_mkdir -p $DIR/$tdir/tmp
3198         local tmp_dir=$DIR/$tdir/tmp
3199         ln -s $DIR/$tdir $tmp_dir/symlink11
3200         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3201         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3202         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3203 }
3204 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3205
3206 test_32f() {
3207         rm -fr $DIR/$tdir
3208         test_mkdir -p $DIR/$tdir/tmp
3209         local tmp_dir=$DIR/$tdir/tmp
3210         ln -s $DIR/$tdir $tmp_dir/symlink11
3211         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3212         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3213         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3214 }
3215 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3216
3217 test_32g() {
3218         local tmp_dir=$DIR/$tdir/tmp
3219         test_mkdir -p $tmp_dir
3220         test_mkdir $DIR/${tdir}2
3221         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3222         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3223         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3224         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3225         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3226         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3227 }
3228 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3229
3230 test_32h() {
3231         rm -fr $DIR/$tdir $DIR/${tdir}2
3232         tmp_dir=$DIR/$tdir/tmp
3233         test_mkdir -p $tmp_dir
3234         test_mkdir $DIR/${tdir}2
3235         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3236         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3237         ls $tmp_dir/symlink12 || error "listing symlink12"
3238         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3239 }
3240 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3241
3242 test_32i() {
3243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3244
3245         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3246         trap cleanup_test32_mount EXIT
3247         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3248         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3249                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3250         touch $DIR/$tdir/test_file
3251         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3252                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3253         cleanup_test32_mount
3254 }
3255 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3256
3257 test_32j() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3259
3260         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3261         trap cleanup_test32_mount EXIT
3262         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3263         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3264                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3265         touch $DIR/$tdir/test_file
3266         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3267                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3268         cleanup_test32_mount
3269 }
3270 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3271
3272 test_32k() {
3273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3274
3275         rm -fr $DIR/$tdir
3276         trap cleanup_test32_mount EXIT
3277         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3278         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3279                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3280         test_mkdir -p $DIR/$tdir/d2
3281         touch $DIR/$tdir/d2/test_file || error "touch failed"
3282         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3283                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3284         cleanup_test32_mount
3285 }
3286 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3287
3288 test_32l() {
3289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3290
3291         rm -fr $DIR/$tdir
3292         trap cleanup_test32_mount EXIT
3293         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3294         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3295                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3296         test_mkdir -p $DIR/$tdir/d2
3297         touch $DIR/$tdir/d2/test_file || error "touch failed"
3298         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3299                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3300         cleanup_test32_mount
3301 }
3302 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3303
3304 test_32m() {
3305         rm -fr $DIR/d32m
3306         test_mkdir -p $DIR/d32m/tmp
3307         TMP_DIR=$DIR/d32m/tmp
3308         ln -s $DIR $TMP_DIR/symlink11
3309         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3310         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3311                 error "symlink11 not a link"
3312         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3313                 error "symlink01 not a link"
3314 }
3315 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3316
3317 test_32n() {
3318         rm -fr $DIR/d32n
3319         test_mkdir -p $DIR/d32n/tmp
3320         TMP_DIR=$DIR/d32n/tmp
3321         ln -s $DIR $TMP_DIR/symlink11
3322         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3323         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3324         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3325 }
3326 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3327
3328 test_32o() {
3329         touch $DIR/$tfile
3330         test_mkdir -p $DIR/d32o/tmp
3331         TMP_DIR=$DIR/d32o/tmp
3332         ln -s $DIR/$tfile $TMP_DIR/symlink12
3333         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3334         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3335                 error "symlink12 not a link"
3336         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3337         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3338                 error "$DIR/d32o/tmp/symlink12 not file type"
3339         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3340                 error "$DIR/d32o/symlink02 not file type"
3341 }
3342 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3343
3344 test_32p() {
3345         log 32p_1
3346         rm -fr $DIR/d32p
3347         log 32p_2
3348         rm -f $DIR/$tfile
3349         log 32p_3
3350         touch $DIR/$tfile
3351         log 32p_4
3352         test_mkdir -p $DIR/d32p/tmp
3353         log 32p_5
3354         TMP_DIR=$DIR/d32p/tmp
3355         log 32p_6
3356         ln -s $DIR/$tfile $TMP_DIR/symlink12
3357         log 32p_7
3358         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3359         log 32p_8
3360         cat $DIR/d32p/tmp/symlink12 ||
3361                 error "Can't open $DIR/d32p/tmp/symlink12"
3362         log 32p_9
3363         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3364         log 32p_10
3365 }
3366 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3367
3368 test_32q() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3375         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3376                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3377         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3378         cleanup_test32_mount
3379 }
3380 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3381
3382 test_32r() {
3383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3384
3385         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3386         trap cleanup_test32_mount EXIT
3387         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3388         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3392         cleanup_test32_mount
3393 }
3394 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3395
3396 test_33aa() {
3397         rm -f $DIR/$tfile
3398         touch $DIR/$tfile
3399         chmod 444 $DIR/$tfile
3400         chown $RUNAS_ID $DIR/$tfile
3401         log 33_1
3402         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3403         log 33_2
3404 }
3405 run_test 33aa "write file with mode 444 (should return error)"
3406
3407 test_33a() {
3408         rm -fr $DIR/$tdir
3409         test_mkdir $DIR/$tdir
3410         chown $RUNAS_ID $DIR/$tdir
3411         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3412                 error "$RUNAS create $tdir/$tfile failed"
3413         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3414                 error "open RDWR" || true
3415 }
3416 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3417
3418 test_33b() {
3419         rm -fr $DIR/$tdir
3420         test_mkdir $DIR/$tdir
3421         chown $RUNAS_ID $DIR/$tdir
3422         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3423 }
3424 run_test 33b "test open file with malformed flags (No panic)"
3425
3426 test_33c() {
3427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3428         remote_ost_nodsh && skip "remote OST with nodsh"
3429
3430         local ostnum
3431         local ostname
3432         local write_bytes
3433         local all_zeros
3434
3435         all_zeros=:
3436         rm -fr $DIR/$tdir
3437         test_mkdir $DIR/$tdir
3438         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3439
3440         sync
3441         for ostnum in $(seq $OSTCOUNT); do
3442                 # test-framework's OST numbering is one-based, while Lustre's
3443                 # is zero-based
3444                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3445                 # Parsing llobdstat's output sucks; we could grep the /proc
3446                 # path, but that's likely to not be as portable as using the
3447                 # llobdstat utility.  So we parse lctl output instead.
3448                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3449                         obdfilter/$ostname/stats |
3450                         awk '/^write_bytes/ {print $7}' )
3451                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3452                 if (( ${write_bytes:-0} > 0 ))
3453                 then
3454                         all_zeros=false
3455                         break;
3456                 fi
3457         done
3458
3459         $all_zeros || return 0
3460
3461         # Write four bytes
3462         echo foo > $DIR/$tdir/bar
3463         # Really write them
3464         sync
3465
3466         # Total up write_bytes after writing.  We'd better find non-zeros.
3467         for ostnum in $(seq $OSTCOUNT); do
3468                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3469                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3470                         obdfilter/$ostname/stats |
3471                         awk '/^write_bytes/ {print $7}' )
3472                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3473                 if (( ${write_bytes:-0} > 0 ))
3474                 then
3475                         all_zeros=false
3476                         break;
3477                 fi
3478         done
3479
3480         if $all_zeros
3481         then
3482                 for ostnum in $(seq $OSTCOUNT); do
3483                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3484                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3485                         do_facet ost$ostnum lctl get_param -n \
3486                                 obdfilter/$ostname/stats
3487                 done
3488                 error "OST not keeping write_bytes stats (b22312)"
3489         fi
3490 }
3491 run_test 33c "test llobdstat and write_bytes"
3492
3493 test_33d() {
3494         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         local MDTIDX=1
3498         local remote_dir=$DIR/$tdir/remote_dir
3499
3500         test_mkdir $DIR/$tdir
3501         $LFS mkdir -i $MDTIDX $remote_dir ||
3502                 error "create remote directory failed"
3503
3504         touch $remote_dir/$tfile
3505         chmod 444 $remote_dir/$tfile
3506         chown $RUNAS_ID $remote_dir/$tfile
3507
3508         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3509
3510         chown $RUNAS_ID $remote_dir
3511         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3512                                         error "create" || true
3513         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3514                                     error "open RDWR" || true
3515         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3516 }
3517 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3518
3519 test_33e() {
3520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3521
3522         mkdir $DIR/$tdir
3523
3524         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3525         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3526         mkdir $DIR/$tdir/local_dir
3527
3528         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3529         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3530         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3531
3532         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3533                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3534
3535         rmdir $DIR/$tdir/* || error "rmdir failed"
3536
3537         umask 777
3538         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3539         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3540         mkdir $DIR/$tdir/local_dir
3541
3542         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3543         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3544         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3545
3546         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3547                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3548
3549         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3550
3551         umask 000
3552         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3553         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3554         mkdir $DIR/$tdir/local_dir
3555
3556         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3557         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3558         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3559
3560         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3561                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3562 }
3563 run_test 33e "mkdir and striped directory should have same mode"
3564
3565 cleanup_33f() {
3566         trap 0
3567         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3568 }
3569
3570 test_33f() {
3571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3572         remote_mds_nodsh && skip "remote MDS with nodsh"
3573
3574         mkdir $DIR/$tdir
3575         chmod go+rwx $DIR/$tdir
3576         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3577         trap cleanup_33f EXIT
3578
3579         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3580                 error "cannot create striped directory"
3581
3582         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3583                 error "cannot create files in striped directory"
3584
3585         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3586                 error "cannot remove files in striped directory"
3587
3588         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3589                 error "cannot remove striped directory"
3590
3591         cleanup_33f
3592 }
3593 run_test 33f "nonroot user can create, access, and remove a striped directory"
3594
3595 test_33g() {
3596         mkdir -p $DIR/$tdir/dir2
3597
3598         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3599         echo $err
3600         [[ $err =~ "exists" ]] || error "Not exists error"
3601 }
3602 run_test 33g "nonroot user create already existing root created file"
3603
3604 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3605 test_34a() {
3606         rm -f $DIR/f34
3607         $MCREATE $DIR/f34 || error "mcreate failed"
3608         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3609                 error "getstripe failed"
3610         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3611         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3612                 error "getstripe failed"
3613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3615 }
3616 run_test 34a "truncate file that has not been opened ==========="
3617
3618 test_34b() {
3619         [ ! -f $DIR/f34 ] && test_34a
3620         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3621                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3622         $OPENFILE -f O_RDONLY $DIR/f34
3623         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3624                 error "getstripe failed"
3625         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3626                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3627 }
3628 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3629
3630 test_34c() {
3631         [ ! -f $DIR/f34 ] && test_34a
3632         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3633                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3634         $OPENFILE -f O_RDWR $DIR/f34
3635         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3636                 error "$LFS getstripe failed"
3637         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3638                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3639 }
3640 run_test 34c "O_RDWR opening file-with-size works =============="
3641
3642 test_34d() {
3643         [ ! -f $DIR/f34 ] && test_34a
3644         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3645                 error "dd failed"
3646         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3647                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3648         rm $DIR/f34
3649 }
3650 run_test 34d "write to sparse file ============================="
3651
3652 test_34e() {
3653         rm -f $DIR/f34e
3654         $MCREATE $DIR/f34e || error "mcreate failed"
3655         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3656         $CHECKSTAT -s 1000 $DIR/f34e ||
3657                 error "Size of $DIR/f34e not equal to 1000 bytes"
3658         $OPENFILE -f O_RDWR $DIR/f34e
3659         $CHECKSTAT -s 1000 $DIR/f34e ||
3660                 error "Size of $DIR/f34e not equal to 1000 bytes"
3661 }
3662 run_test 34e "create objects, some with size and some without =="
3663
3664 test_34f() { # bug 6242, 6243
3665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3666
3667         SIZE34F=48000
3668         rm -f $DIR/f34f
3669         $MCREATE $DIR/f34f || error "mcreate failed"
3670         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3671         dd if=$DIR/f34f of=$TMP/f34f
3672         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3673         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3674         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3675         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3676         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3677 }
3678 run_test 34f "read from a file with no objects until EOF ======="
3679
3680 test_34g() {
3681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3682
3683         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3684                 error "dd failed"
3685         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3686         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3687                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3688         cancel_lru_locks osc
3689         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3690                 error "wrong size after lock cancel"
3691
3692         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3693         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3694                 error "expanding truncate failed"
3695         cancel_lru_locks osc
3696         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3697                 error "wrong expanded size after lock cancel"
3698 }
3699 run_test 34g "truncate long file ==============================="
3700
3701 test_34h() {
3702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3703
3704         local gid=10
3705         local sz=1000
3706
3707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3708         sync # Flush the cache so that multiop below does not block on cache
3709              # flush when getting the group lock
3710         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3711         MULTIPID=$!
3712
3713         # Since just timed wait is not good enough, let's do a sync write
3714         # that way we are sure enough time for a roundtrip + processing
3715         # passed + 2 seconds of extra margin.
3716         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3717         rm $DIR/${tfile}-1
3718         sleep 2
3719
3720         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3721                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3722                 kill -9 $MULTIPID
3723         fi
3724         wait $MULTIPID
3725         local nsz=`stat -c %s $DIR/$tfile`
3726         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3727 }
3728 run_test 34h "ftruncate file under grouplock should not block"
3729
3730 test_35a() {
3731         cp /bin/sh $DIR/f35a
3732         chmod 444 $DIR/f35a
3733         chown $RUNAS_ID $DIR/f35a
3734         $RUNAS $DIR/f35a && error || true
3735         rm $DIR/f35a
3736 }
3737 run_test 35a "exec file with mode 444 (should return and not leak)"
3738
3739 test_36a() {
3740         rm -f $DIR/f36
3741         utime $DIR/f36 || error "utime failed for MDS"
3742 }
3743 run_test 36a "MDS utime check (mknod, utime)"
3744
3745 test_36b() {
3746         echo "" > $DIR/f36
3747         utime $DIR/f36 || error "utime failed for OST"
3748 }
3749 run_test 36b "OST utime check (open, utime)"
3750
3751 test_36c() {
3752         rm -f $DIR/d36/f36
3753         test_mkdir $DIR/d36
3754         chown $RUNAS_ID $DIR/d36
3755         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3756 }
3757 run_test 36c "non-root MDS utime check (mknod, utime)"
3758
3759 test_36d() {
3760         [ ! -d $DIR/d36 ] && test_36c
3761         echo "" > $DIR/d36/f36
3762         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3763 }
3764 run_test 36d "non-root OST utime check (open, utime)"
3765
3766 test_36e() {
3767         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3768
3769         test_mkdir $DIR/$tdir
3770         touch $DIR/$tdir/$tfile
3771         $RUNAS utime $DIR/$tdir/$tfile &&
3772                 error "utime worked, expected failure" || true
3773 }
3774 run_test 36e "utime on non-owned file (should return error)"
3775
3776 subr_36fh() {
3777         local fl="$1"
3778         local LANG_SAVE=$LANG
3779         local LC_LANG_SAVE=$LC_LANG
3780         export LANG=C LC_LANG=C # for date language
3781
3782         DATESTR="Dec 20  2000"
3783         test_mkdir $DIR/$tdir
3784         lctl set_param fail_loc=$fl
3785         date; date +%s
3786         cp /etc/hosts $DIR/$tdir/$tfile
3787         sync & # write RPC generated with "current" inode timestamp, but delayed
3788         sleep 1
3789         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3790         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3791         cancel_lru_locks $OSC
3792         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3793         date; date +%s
3794         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3795                 echo "BEFORE: $LS_BEFORE" && \
3796                 echo "AFTER : $LS_AFTER" && \
3797                 echo "WANT  : $DATESTR" && \
3798                 error "$DIR/$tdir/$tfile timestamps changed" || true
3799
3800         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3801 }
3802
3803 test_36f() {
3804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3805
3806         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3807         subr_36fh "0x80000214"
3808 }
3809 run_test 36f "utime on file racing with OST BRW write =========="
3810
3811 test_36g() {
3812         remote_ost_nodsh && skip "remote OST with nodsh"
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3815                 skip "Need MDS version at least 2.12.51"
3816
3817         local fmd_max_age
3818         local fmd
3819         local facet="ost1"
3820         local tgt="obdfilter"
3821
3822         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3823
3824         test_mkdir $DIR/$tdir
3825         fmd_max_age=$(do_facet $facet \
3826                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3827                 head -n 1")
3828
3829         echo "FMD max age: ${fmd_max_age}s"
3830         touch $DIR/$tdir/$tfile
3831         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3832                 gawk '{cnt=cnt+$1}  END{print cnt}')
3833         echo "FMD before: $fmd"
3834         [[ $fmd == 0 ]] &&
3835                 error "FMD wasn't create by touch"
3836         sleep $((fmd_max_age + 12))
3837         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3838                 gawk '{cnt=cnt+$1}  END{print cnt}')
3839         echo "FMD after: $fmd"
3840         [[ $fmd == 0 ]] ||
3841                 error "FMD wasn't expired by ping"
3842 }
3843 run_test 36g "FMD cache expiry ====================="
3844
3845 test_36h() {
3846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3847
3848         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3849         subr_36fh "0x80000227"
3850 }
3851 run_test 36h "utime on file racing with OST BRW write =========="
3852
3853 test_36i() {
3854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3855
3856         test_mkdir $DIR/$tdir
3857         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3858
3859         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3860         local new_mtime=$((mtime + 200))
3861
3862         #change Modify time of striped dir
3863         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3864                         error "change mtime failed"
3865
3866         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3867
3868         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3869 }
3870 run_test 36i "change mtime on striped directory"
3871
3872 # test_37 - duplicate with tests 32q 32r
3873
3874 test_38() {
3875         local file=$DIR/$tfile
3876         touch $file
3877         openfile -f O_DIRECTORY $file
3878         local RC=$?
3879         local ENOTDIR=20
3880         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3881         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3882 }
3883 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3884
3885 test_39a() { # was test_39
3886         touch $DIR/$tfile
3887         touch $DIR/${tfile}2
3888 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3889 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3890 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3891         sleep 2
3892         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3893         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3894                 echo "mtime"
3895                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3896                 echo "atime"
3897                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3898                 echo "ctime"
3899                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3900                 error "O_TRUNC didn't change timestamps"
3901         fi
3902 }
3903 run_test 39a "mtime changed on create"
3904
3905 test_39b() {
3906         test_mkdir -c1 $DIR/$tdir
3907         cp -p /etc/passwd $DIR/$tdir/fopen
3908         cp -p /etc/passwd $DIR/$tdir/flink
3909         cp -p /etc/passwd $DIR/$tdir/funlink
3910         cp -p /etc/passwd $DIR/$tdir/frename
3911         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3912
3913         sleep 1
3914         echo "aaaaaa" >> $DIR/$tdir/fopen
3915         echo "aaaaaa" >> $DIR/$tdir/flink
3916         echo "aaaaaa" >> $DIR/$tdir/funlink
3917         echo "aaaaaa" >> $DIR/$tdir/frename
3918
3919         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3920         local link_new=`stat -c %Y $DIR/$tdir/flink`
3921         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3922         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3923
3924         cat $DIR/$tdir/fopen > /dev/null
3925         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3926         rm -f $DIR/$tdir/funlink2
3927         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3928
3929         for (( i=0; i < 2; i++ )) ; do
3930                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3931                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3932                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3933                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3934
3935                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3936                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3937                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3938                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3939
3940                 cancel_lru_locks $OSC
3941                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3942         done
3943 }
3944 run_test 39b "mtime change on open, link, unlink, rename  ======"
3945
3946 # this should be set to past
3947 TEST_39_MTIME=`date -d "1 year ago" +%s`
3948
3949 # bug 11063
3950 test_39c() {
3951         touch $DIR1/$tfile
3952         sleep 2
3953         local mtime0=`stat -c %Y $DIR1/$tfile`
3954
3955         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3956         local mtime1=`stat -c %Y $DIR1/$tfile`
3957         [ "$mtime1" = $TEST_39_MTIME ] || \
3958                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3959
3960         local d1=`date +%s`
3961         echo hello >> $DIR1/$tfile
3962         local d2=`date +%s`
3963         local mtime2=`stat -c %Y $DIR1/$tfile`
3964         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3965                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3966
3967         mv $DIR1/$tfile $DIR1/$tfile-1
3968
3969         for (( i=0; i < 2; i++ )) ; do
3970                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3971                 [ "$mtime2" = "$mtime3" ] || \
3972                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3973
3974                 cancel_lru_locks $OSC
3975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3976         done
3977 }
3978 run_test 39c "mtime change on rename ==========================="
3979
3980 # bug 21114
3981 test_39d() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983
3984         touch $DIR1/$tfile
3985         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3986
3987         for (( i=0; i < 2; i++ )) ; do
3988                 local mtime=`stat -c %Y $DIR1/$tfile`
3989                 [ $mtime = $TEST_39_MTIME ] || \
3990                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3991
3992                 cancel_lru_locks $OSC
3993                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3994         done
3995 }
3996 run_test 39d "create, utime, stat =============================="
3997
3998 # bug 21114
3999 test_39e() {
4000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4001
4002         touch $DIR1/$tfile
4003         local mtime1=`stat -c %Y $DIR1/$tfile`
4004
4005         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4006
4007         for (( i=0; i < 2; i++ )) ; do
4008                 local mtime2=`stat -c %Y $DIR1/$tfile`
4009                 [ $mtime2 = $TEST_39_MTIME ] || \
4010                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4011
4012                 cancel_lru_locks $OSC
4013                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4014         done
4015 }
4016 run_test 39e "create, stat, utime, stat ========================"
4017
4018 # bug 21114
4019 test_39f() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         touch $DIR1/$tfile
4023         mtime1=`stat -c %Y $DIR1/$tfile`
4024
4025         sleep 2
4026         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4027
4028         for (( i=0; i < 2; i++ )) ; do
4029                 local mtime2=`stat -c %Y $DIR1/$tfile`
4030                 [ $mtime2 = $TEST_39_MTIME ] || \
4031                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4032
4033                 cancel_lru_locks $OSC
4034                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4035         done
4036 }
4037 run_test 39f "create, stat, sleep, utime, stat ================="
4038
4039 # bug 11063
4040 test_39g() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         echo hello >> $DIR1/$tfile
4044         local mtime1=`stat -c %Y $DIR1/$tfile`
4045
4046         sleep 2
4047         chmod o+r $DIR1/$tfile
4048
4049         for (( i=0; i < 2; i++ )) ; do
4050                 local mtime2=`stat -c %Y $DIR1/$tfile`
4051                 [ "$mtime1" = "$mtime2" ] || \
4052                         error "lost mtime: $mtime2, should be $mtime1"
4053
4054                 cancel_lru_locks $OSC
4055                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4056         done
4057 }
4058 run_test 39g "write, chmod, stat ==============================="
4059
4060 # bug 11063
4061 test_39h() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         touch $DIR1/$tfile
4065         sleep 1
4066
4067         local d1=`date`
4068         echo hello >> $DIR1/$tfile
4069         local mtime1=`stat -c %Y $DIR1/$tfile`
4070
4071         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4072         local d2=`date`
4073         if [ "$d1" != "$d2" ]; then
4074                 echo "write and touch not within one second"
4075         else
4076                 for (( i=0; i < 2; i++ )) ; do
4077                         local mtime2=`stat -c %Y $DIR1/$tfile`
4078                         [ "$mtime2" = $TEST_39_MTIME ] || \
4079                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4080
4081                         cancel_lru_locks $OSC
4082                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4083                 done
4084         fi
4085 }
4086 run_test 39h "write, utime within one second, stat ============="
4087
4088 test_39i() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         touch $DIR1/$tfile
4092         sleep 1
4093
4094         echo hello >> $DIR1/$tfile
4095         local mtime1=`stat -c %Y $DIR1/$tfile`
4096
4097         mv $DIR1/$tfile $DIR1/$tfile-1
4098
4099         for (( i=0; i < 2; i++ )) ; do
4100                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4101
4102                 [ "$mtime1" = "$mtime2" ] || \
4103                         error "lost mtime: $mtime2, should be $mtime1"
4104
4105                 cancel_lru_locks $OSC
4106                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4107         done
4108 }
4109 run_test 39i "write, rename, stat =============================="
4110
4111 test_39j() {
4112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4113
4114         start_full_debug_logging
4115         touch $DIR1/$tfile
4116         sleep 1
4117
4118         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4119         lctl set_param fail_loc=0x80000412
4120         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4121                 error "multiop failed"
4122         local multipid=$!
4123         local mtime1=`stat -c %Y $DIR1/$tfile`
4124
4125         mv $DIR1/$tfile $DIR1/$tfile-1
4126
4127         kill -USR1 $multipid
4128         wait $multipid || error "multiop close failed"
4129
4130         for (( i=0; i < 2; i++ )) ; do
4131                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4132                 [ "$mtime1" = "$mtime2" ] ||
4133                         error "mtime is lost on close: $mtime2, " \
4134                               "should be $mtime1"
4135
4136                 cancel_lru_locks $OSC
4137                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4138         done
4139         lctl set_param fail_loc=0
4140         stop_full_debug_logging
4141 }
4142 run_test 39j "write, rename, close, stat ======================="
4143
4144 test_39k() {
4145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4146
4147         touch $DIR1/$tfile
4148         sleep 1
4149
4150         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4151         local multipid=$!
4152         local mtime1=`stat -c %Y $DIR1/$tfile`
4153
4154         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4155
4156         kill -USR1 $multipid
4157         wait $multipid || error "multiop close failed"
4158
4159         for (( i=0; i < 2; i++ )) ; do
4160                 local mtime2=`stat -c %Y $DIR1/$tfile`
4161
4162                 [ "$mtime2" = $TEST_39_MTIME ] || \
4163                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4164
4165                 cancel_lru_locks osc
4166                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4167         done
4168 }
4169 run_test 39k "write, utime, close, stat ========================"
4170
4171 # this should be set to future
4172 TEST_39_ATIME=`date -d "1 year" +%s`
4173
4174 test_39l() {
4175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4176         remote_mds_nodsh && skip "remote MDS with nodsh"
4177
4178         local atime_diff=$(do_facet $SINGLEMDS \
4179                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4180         rm -rf $DIR/$tdir
4181         mkdir -p $DIR/$tdir
4182
4183         # test setting directory atime to future
4184         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4185         local atime=$(stat -c %X $DIR/$tdir)
4186         [ "$atime" = $TEST_39_ATIME ] ||
4187                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4188
4189         # test setting directory atime from future to now
4190         local now=$(date +%s)
4191         touch -a -d @$now $DIR/$tdir
4192
4193         atime=$(stat -c %X $DIR/$tdir)
4194         [ "$atime" -eq "$now"  ] ||
4195                 error "atime is not updated from future: $atime, $now"
4196
4197         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4198         sleep 3
4199
4200         # test setting directory atime when now > dir atime + atime_diff
4201         local d1=$(date +%s)
4202         ls $DIR/$tdir
4203         local d2=$(date +%s)
4204         cancel_lru_locks mdc
4205         atime=$(stat -c %X $DIR/$tdir)
4206         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4207                 error "atime is not updated  : $atime, should be $d2"
4208
4209         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4210         sleep 3
4211
4212         # test not setting directory atime when now < dir atime + atime_diff
4213         ls $DIR/$tdir
4214         cancel_lru_locks mdc
4215         atime=$(stat -c %X $DIR/$tdir)
4216         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4217                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4218
4219         do_facet $SINGLEMDS \
4220                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4221 }
4222 run_test 39l "directory atime update ==========================="
4223
4224 test_39m() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         sleep 2
4229         local far_past_mtime=$(date -d "May 29 1953" +%s)
4230         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4231
4232         touch -m -d @$far_past_mtime $DIR1/$tfile
4233         touch -a -d @$far_past_atime $DIR1/$tfile
4234
4235         for (( i=0; i < 2; i++ )) ; do
4236                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4237                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4238                         error "atime or mtime set incorrectly"
4239
4240                 cancel_lru_locks $OSC
4241                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4242         done
4243 }
4244 run_test 39m "test atime and mtime before 1970"
4245
4246 test_39n() { # LU-3832
4247         remote_mds_nodsh && skip "remote MDS with nodsh"
4248
4249         local atime_diff=$(do_facet $SINGLEMDS \
4250                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4251         local atime0
4252         local atime1
4253         local atime2
4254
4255         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4256
4257         rm -rf $DIR/$tfile
4258         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4259         atime0=$(stat -c %X $DIR/$tfile)
4260
4261         sleep 5
4262         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4263         atime1=$(stat -c %X $DIR/$tfile)
4264
4265         sleep 5
4266         cancel_lru_locks mdc
4267         cancel_lru_locks osc
4268         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4269         atime2=$(stat -c %X $DIR/$tfile)
4270
4271         do_facet $SINGLEMDS \
4272                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4273
4274         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4275         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4276 }
4277 run_test 39n "check that O_NOATIME is honored"
4278
4279 test_39o() {
4280         TESTDIR=$DIR/$tdir/$tfile
4281         [ -e $TESTDIR ] && rm -rf $TESTDIR
4282         mkdir -p $TESTDIR
4283         cd $TESTDIR
4284         links1=2
4285         ls
4286         mkdir a b
4287         ls
4288         links2=$(stat -c %h .)
4289         [ $(($links1 + 2)) != $links2 ] &&
4290                 error "wrong links count $(($links1 + 2)) != $links2"
4291         rmdir b
4292         links3=$(stat -c %h .)
4293         [ $(($links1 + 1)) != $links3 ] &&
4294                 error "wrong links count $links1 != $links3"
4295         return 0
4296 }
4297 run_test 39o "directory cached attributes updated after create"
4298
4299 test_39p() {
4300         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4301
4302         local MDTIDX=1
4303         TESTDIR=$DIR/$tdir/$tdir
4304         [ -e $TESTDIR ] && rm -rf $TESTDIR
4305         test_mkdir -p $TESTDIR
4306         cd $TESTDIR
4307         links1=2
4308         ls
4309         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4310         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4311         ls
4312         links2=$(stat -c %h .)
4313         [ $(($links1 + 2)) != $links2 ] &&
4314                 error "wrong links count $(($links1 + 2)) != $links2"
4315         rmdir remote_dir2
4316         links3=$(stat -c %h .)
4317         [ $(($links1 + 1)) != $links3 ] &&
4318                 error "wrong links count $links1 != $links3"
4319         return 0
4320 }
4321 run_test 39p "remote directory cached attributes updated after create ========"
4322
4323
4324 test_39q() { # LU-8041
4325         local testdir=$DIR/$tdir
4326         mkdir -p $testdir
4327         multiop_bg_pause $testdir D_c || error "multiop failed"
4328         local multipid=$!
4329         cancel_lru_locks mdc
4330         kill -USR1 $multipid
4331         local atime=$(stat -c %X $testdir)
4332         [ "$atime" -ne 0 ] || error "atime is zero"
4333 }
4334 run_test 39q "close won't zero out atime"
4335
4336 test_40() {
4337         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4338         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4339                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4340         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4341                 error "$tfile is not 4096 bytes in size"
4342 }
4343 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4344
4345 test_41() {
4346         # bug 1553
4347         small_write $DIR/f41 18
4348 }
4349 run_test 41 "test small file write + fstat ====================="
4350
4351 count_ost_writes() {
4352         lctl get_param -n ${OSC}.*.stats |
4353                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4354                         END { printf("%0.0f", writes) }'
4355 }
4356
4357 # decent default
4358 WRITEBACK_SAVE=500
4359 DIRTY_RATIO_SAVE=40
4360 MAX_DIRTY_RATIO=50
4361 BG_DIRTY_RATIO_SAVE=10
4362 MAX_BG_DIRTY_RATIO=25
4363
4364 start_writeback() {
4365         trap 0
4366         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4367         # dirty_ratio, dirty_background_ratio
4368         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4369                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4370                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4371                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4372         else
4373                 # if file not here, we are a 2.4 kernel
4374                 kill -CONT `pidof kupdated`
4375         fi
4376 }
4377
4378 stop_writeback() {
4379         # setup the trap first, so someone cannot exit the test at the
4380         # exact wrong time and mess up a machine
4381         trap start_writeback EXIT
4382         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4383         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4384                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4385                 sysctl -w vm.dirty_writeback_centisecs=0
4386                 sysctl -w vm.dirty_writeback_centisecs=0
4387                 # save and increase /proc/sys/vm/dirty_ratio
4388                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4389                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4390                 # save and increase /proc/sys/vm/dirty_background_ratio
4391                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4392                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4393         else
4394                 # if file not here, we are a 2.4 kernel
4395                 kill -STOP `pidof kupdated`
4396         fi
4397 }
4398
4399 # ensure that all stripes have some grant before we test client-side cache
4400 setup_test42() {
4401         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4402                 dd if=/dev/zero of=$i bs=4k count=1
4403                 rm $i
4404         done
4405 }
4406
4407 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4408 # file truncation, and file removal.
4409 test_42a() {
4410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4411
4412         setup_test42
4413         cancel_lru_locks $OSC
4414         stop_writeback
4415         sync; sleep 1; sync # just to be safe
4416         BEFOREWRITES=`count_ost_writes`
4417         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4418         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4419         AFTERWRITES=`count_ost_writes`
4420         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4421                 error "$BEFOREWRITES < $AFTERWRITES"
4422         start_writeback
4423 }
4424 run_test 42a "ensure that we don't flush on close"
4425
4426 test_42b() {
4427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4428
4429         setup_test42
4430         cancel_lru_locks $OSC
4431         stop_writeback
4432         sync
4433         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4434         BEFOREWRITES=$(count_ost_writes)
4435         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4436         AFTERWRITES=$(count_ost_writes)
4437         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4438                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4439         fi
4440         BEFOREWRITES=$(count_ost_writes)
4441         sync || error "sync: $?"
4442         AFTERWRITES=$(count_ost_writes)
4443         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4444                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4445         fi
4446         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4447         start_writeback
4448         return 0
4449 }
4450 run_test 42b "test destroy of file with cached dirty data ======"
4451
4452 # if these tests just want to test the effect of truncation,
4453 # they have to be very careful.  consider:
4454 # - the first open gets a {0,EOF}PR lock
4455 # - the first write conflicts and gets a {0, count-1}PW
4456 # - the rest of the writes are under {count,EOF}PW
4457 # - the open for truncate tries to match a {0,EOF}PR
4458 #   for the filesize and cancels the PWs.
4459 # any number of fixes (don't get {0,EOF} on open, match
4460 # composite locks, do smarter file size management) fix
4461 # this, but for now we want these tests to verify that
4462 # the cancellation with truncate intent works, so we
4463 # start the file with a full-file pw lock to match against
4464 # until the truncate.
4465 trunc_test() {
4466         test=$1
4467         file=$DIR/$test
4468         offset=$2
4469         cancel_lru_locks $OSC
4470         stop_writeback
4471         # prime the file with 0,EOF PW to match
4472         touch $file
4473         $TRUNCATE $file 0
4474         sync; sync
4475         # now the real test..
4476         dd if=/dev/zero of=$file bs=1024 count=100
4477         BEFOREWRITES=`count_ost_writes`
4478         $TRUNCATE $file $offset
4479         cancel_lru_locks $OSC
4480         AFTERWRITES=`count_ost_writes`
4481         start_writeback
4482 }
4483
4484 test_42c() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         trunc_test 42c 1024
4488         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4489                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4490         rm $file
4491 }
4492 run_test 42c "test partial truncate of file with cached dirty data"
4493
4494 test_42d() {
4495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4496
4497         trunc_test 42d 0
4498         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4499                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4500         rm $file
4501 }
4502 run_test 42d "test complete truncate of file with cached dirty data"
4503
4504 test_42e() { # bug22074
4505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4506
4507         local TDIR=$DIR/${tdir}e
4508         local pages=16 # hardcoded 16 pages, don't change it.
4509         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4510         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4511         local max_dirty_mb
4512         local warmup_files
4513
4514         test_mkdir $DIR/${tdir}e
4515         $LFS setstripe -c 1 $TDIR
4516         createmany -o $TDIR/f $files
4517
4518         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4519
4520         # we assume that with $OSTCOUNT files, at least one of them will
4521         # be allocated on OST0.
4522         warmup_files=$((OSTCOUNT * max_dirty_mb))
4523         createmany -o $TDIR/w $warmup_files
4524
4525         # write a large amount of data into one file and sync, to get good
4526         # avail_grant number from OST.
4527         for ((i=0; i<$warmup_files; i++)); do
4528                 idx=$($LFS getstripe -i $TDIR/w$i)
4529                 [ $idx -ne 0 ] && continue
4530                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4531                 break
4532         done
4533         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4534         sync
4535         $LCTL get_param $proc_osc0/cur_dirty_bytes
4536         $LCTL get_param $proc_osc0/cur_grant_bytes
4537
4538         # create as much dirty pages as we can while not to trigger the actual
4539         # RPCs directly. but depends on the env, VFS may trigger flush during this
4540         # period, hopefully we are good.
4541         for ((i=0; i<$warmup_files; i++)); do
4542                 idx=$($LFS getstripe -i $TDIR/w$i)
4543                 [ $idx -ne 0 ] && continue
4544                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4545         done
4546         $LCTL get_param $proc_osc0/cur_dirty_bytes
4547         $LCTL get_param $proc_osc0/cur_grant_bytes
4548
4549         # perform the real test
4550         $LCTL set_param $proc_osc0/rpc_stats 0
4551         for ((;i<$files; i++)); do
4552                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4553                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4554         done
4555         sync
4556         $LCTL get_param $proc_osc0/rpc_stats
4557
4558         local percent=0
4559         local have_ppr=false
4560         $LCTL get_param $proc_osc0/rpc_stats |
4561                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4562                         # skip lines until we are at the RPC histogram data
4563                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4564                         $have_ppr || continue
4565
4566                         # we only want the percent stat for < 16 pages
4567                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4568
4569                         percent=$((percent + WPCT))
4570                         if [[ $percent -gt 15 ]]; then
4571                                 error "less than 16-pages write RPCs" \
4572                                       "$percent% > 15%"
4573                                 break
4574                         fi
4575                 done
4576         rm -rf $TDIR
4577 }
4578 run_test 42e "verify sub-RPC writes are not done synchronously"
4579
4580 test_43A() { # was test_43
4581         test_mkdir $DIR/$tdir
4582         cp -p /bin/ls $DIR/$tdir/$tfile
4583         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4584         pid=$!
4585         # give multiop a chance to open
4586         sleep 1
4587
4588         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4589         kill -USR1 $pid
4590 }
4591 run_test 43A "execution of file opened for write should return -ETXTBSY"
4592
4593 test_43a() {
4594         test_mkdir $DIR/$tdir
4595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4596         $DIR/$tdir/sleep 60 &
4597         SLEEP_PID=$!
4598         # Make sure exec of $tdir/sleep wins race with truncate
4599         sleep 1
4600         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4601         kill $SLEEP_PID
4602 }
4603 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4604
4605 test_43b() {
4606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4607
4608         test_mkdir $DIR/$tdir
4609         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4610         $DIR/$tdir/sleep 60 &
4611         SLEEP_PID=$!
4612         # Make sure exec of $tdir/sleep wins race with truncate
4613         sleep 1
4614         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4615         kill $SLEEP_PID
4616 }
4617 run_test 43b "truncate of file being executed should return -ETXTBSY"
4618
4619 test_43c() {
4620         local testdir="$DIR/$tdir"
4621         test_mkdir $testdir
4622         cp $SHELL $testdir/
4623         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4624                 ( cd $testdir && md5sum -c )
4625 }
4626 run_test 43c "md5sum of copy into lustre"
4627
4628 test_44A() { # was test_44
4629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4630
4631         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4632         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4633 }
4634 run_test 44A "zero length read from a sparse stripe"
4635
4636 test_44a() {
4637         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4638                 awk '{ print $2 }')
4639         [ -z "$nstripe" ] && skip "can't get stripe info"
4640         [[ $nstripe -gt $OSTCOUNT ]] &&
4641                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4642
4643         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4644                 awk '{ print $2 }')
4645         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4646                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4647                         awk '{ print $2 }')
4648         fi
4649
4650         OFFSETS="0 $((stride/2)) $((stride-1))"
4651         for offset in $OFFSETS; do
4652                 for i in $(seq 0 $((nstripe-1))); do
4653                         local GLOBALOFFSETS=""
4654                         # size in Bytes
4655                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4656                         local myfn=$DIR/d44a-$size
4657                         echo "--------writing $myfn at $size"
4658                         ll_sparseness_write $myfn $size ||
4659                                 error "ll_sparseness_write"
4660                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4661                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4662                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4663
4664                         for j in $(seq 0 $((nstripe-1))); do
4665                                 # size in Bytes
4666                                 size=$((((j + $nstripe )*$stride + $offset)))
4667                                 ll_sparseness_write $myfn $size ||
4668                                         error "ll_sparseness_write"
4669                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4670                         done
4671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4673                         rm -f $myfn
4674                 done
4675         done
4676 }
4677 run_test 44a "test sparse pwrite ==============================="
4678
4679 dirty_osc_total() {
4680         tot=0
4681         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4682                 tot=$(($tot + $d))
4683         done
4684         echo $tot
4685 }
4686 do_dirty_record() {
4687         before=`dirty_osc_total`
4688         echo executing "\"$*\""
4689         eval $*
4690         after=`dirty_osc_total`
4691         echo before $before, after $after
4692 }
4693 test_45() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         f="$DIR/f45"
4697         # Obtain grants from OST if it supports it
4698         echo blah > ${f}_grant
4699         stop_writeback
4700         sync
4701         do_dirty_record "echo blah > $f"
4702         [[ $before -eq $after ]] && error "write wasn't cached"
4703         do_dirty_record "> $f"
4704         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4705         do_dirty_record "echo blah > $f"
4706         [[ $before -eq $after ]] && error "write wasn't cached"
4707         do_dirty_record "sync"
4708         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4709         do_dirty_record "echo blah > $f"
4710         [[ $before -eq $after ]] && error "write wasn't cached"
4711         do_dirty_record "cancel_lru_locks osc"
4712         [[ $before -gt $after ]] ||
4713                 error "lock cancellation didn't lower dirty count"
4714         start_writeback
4715 }
4716 run_test 45 "osc io page accounting ============================"
4717
4718 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4719 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4720 # objects offset and an assert hit when an rpc was built with 1023's mapped
4721 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4722 test_46() {
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724
4725         f="$DIR/f46"
4726         stop_writeback
4727         sync
4728         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4729         sync
4730         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4731         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4732         sync
4733         start_writeback
4734 }
4735 run_test 46 "dirtying a previously written page ================"
4736
4737 # test_47 is removed "Device nodes check" is moved to test_28
4738
4739 test_48a() { # bug 2399
4740         [ "$mds1_FSTYPE" = "zfs" ] &&
4741         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4742                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4743
4744         test_mkdir $DIR/$tdir
4745         cd $DIR/$tdir
4746         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4747         test_mkdir $DIR/$tdir
4748         touch foo || error "'touch foo' failed after recreating cwd"
4749         test_mkdir bar
4750         touch .foo || error "'touch .foo' failed after recreating cwd"
4751         test_mkdir .bar
4752         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4753         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4754         cd . || error "'cd .' failed after recreating cwd"
4755         mkdir . && error "'mkdir .' worked after recreating cwd"
4756         rmdir . && error "'rmdir .' worked after recreating cwd"
4757         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4758         cd .. || error "'cd ..' failed after recreating cwd"
4759 }
4760 run_test 48a "Access renamed working dir (should return errors)="
4761
4762 test_48b() { # bug 2399
4763         rm -rf $DIR/$tdir
4764         test_mkdir $DIR/$tdir
4765         cd $DIR/$tdir
4766         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4767         touch foo && error "'touch foo' worked after removing cwd"
4768         mkdir foo && error "'mkdir foo' worked after removing cwd"
4769         touch .foo && error "'touch .foo' worked after removing cwd"
4770         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4771         ls . > /dev/null && error "'ls .' worked after removing cwd"
4772         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4773         mkdir . && error "'mkdir .' worked after removing cwd"
4774         rmdir . && error "'rmdir .' worked after removing cwd"
4775         ln -s . foo && error "'ln -s .' worked after removing cwd"
4776         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4777 }
4778 run_test 48b "Access removed working dir (should return errors)="
4779
4780 test_48c() { # bug 2350
4781         #lctl set_param debug=-1
4782         #set -vx
4783         rm -rf $DIR/$tdir
4784         test_mkdir -p $DIR/$tdir/dir
4785         cd $DIR/$tdir/dir
4786         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4787         $TRACE touch foo && error "touch foo worked after removing cwd"
4788         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4789         touch .foo && error "touch .foo worked after removing cwd"
4790         mkdir .foo && error "mkdir .foo worked after removing cwd"
4791         $TRACE ls . && error "'ls .' worked after removing cwd"
4792         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4793         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4794         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4795         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4796         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4797 }
4798 run_test 48c "Access removed working subdir (should return errors)"
4799
4800 test_48d() { # bug 2350
4801         #lctl set_param debug=-1
4802         #set -vx
4803         rm -rf $DIR/$tdir
4804         test_mkdir -p $DIR/$tdir/dir
4805         cd $DIR/$tdir/dir
4806         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4807         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4808         $TRACE touch foo && error "'touch foo' worked after removing parent"
4809         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4810         touch .foo && error "'touch .foo' worked after removing parent"
4811         mkdir .foo && error "mkdir .foo worked after removing parent"
4812         $TRACE ls . && error "'ls .' worked after removing parent"
4813         $TRACE ls .. && error "'ls ..' worked after removing parent"
4814         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4815         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4816         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4817         true
4818 }
4819 run_test 48d "Access removed parent subdir (should return errors)"
4820
4821 test_48e() { # bug 4134
4822         #lctl set_param debug=-1
4823         #set -vx
4824         rm -rf $DIR/$tdir
4825         test_mkdir -p $DIR/$tdir/dir
4826         cd $DIR/$tdir/dir
4827         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4828         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4829         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4830         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4831         # On a buggy kernel addition of "touch foo" after cd .. will
4832         # produce kernel oops in lookup_hash_it
4833         touch ../foo && error "'cd ..' worked after recreate parent"
4834         cd $DIR
4835         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4836 }
4837 run_test 48e "Access to recreated parent subdir (should return errors)"
4838
4839 test_49() { # LU-1030
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841         remote_ost_nodsh && skip "remote OST with nodsh"
4842
4843         # get ost1 size - lustre-OST0000
4844         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4845                 awk '{ print $4 }')
4846         # write 800M at maximum
4847         [[ $ost1_size -lt 2 ]] && ost1_size=2
4848         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4849
4850         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4851         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4852         local dd_pid=$!
4853
4854         # change max_pages_per_rpc while writing the file
4855         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4856         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4857         # loop until dd process exits
4858         while ps ax -opid | grep -wq $dd_pid; do
4859                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4860                 sleep $((RANDOM % 5 + 1))
4861         done
4862         # restore original max_pages_per_rpc
4863         $LCTL set_param $osc1_mppc=$orig_mppc
4864         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4865 }
4866 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4867
4868 test_50() {
4869         # bug 1485
4870         test_mkdir $DIR/$tdir
4871         cd $DIR/$tdir
4872         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4873 }
4874 run_test 50 "special situations: /proc symlinks  ==============="
4875
4876 test_51a() {    # was test_51
4877         # bug 1516 - create an empty entry right after ".." then split dir
4878         test_mkdir -c1 $DIR/$tdir
4879         touch $DIR/$tdir/foo
4880         $MCREATE $DIR/$tdir/bar
4881         rm $DIR/$tdir/foo
4882         createmany -m $DIR/$tdir/longfile 201
4883         FNUM=202
4884         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4885                 $MCREATE $DIR/$tdir/longfile$FNUM
4886                 FNUM=$(($FNUM + 1))
4887                 echo -n "+"
4888         done
4889         echo
4890         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4891 }
4892 run_test 51a "special situations: split htree with empty entry =="
4893
4894 cleanup_print_lfs_df () {
4895         trap 0
4896         $LFS df
4897         $LFS df -i
4898 }
4899
4900 test_51b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         local dir=$DIR/$tdir
4904         local nrdirs=$((65536 + 100))
4905
4906         # cleanup the directory
4907         rm -fr $dir
4908
4909         test_mkdir -c1 $dir
4910
4911         $LFS df
4912         $LFS df -i
4913         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4914         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4915         [[ $numfree -lt $nrdirs ]] &&
4916                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4917
4918         # need to check free space for the directories as well
4919         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4920         numfree=$(( blkfree / $(fs_inode_ksize) ))
4921         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4922
4923         trap cleanup_print_lfs_df EXIT
4924
4925         # create files
4926         createmany -d $dir/d $nrdirs || {
4927                 unlinkmany $dir/d $nrdirs
4928                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4929         }
4930
4931         # really created :
4932         nrdirs=$(ls -U $dir | wc -l)
4933
4934         # unlink all but 100 subdirectories, then check it still works
4935         local left=100
4936         local delete=$((nrdirs - left))
4937
4938         $LFS df
4939         $LFS df -i
4940
4941         # for ldiskfs the nlink count should be 1, but this is OSD specific
4942         # and so this is listed for informational purposes only
4943         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4944         unlinkmany -d $dir/d $delete ||
4945                 error "unlink of first $delete subdirs failed"
4946
4947         echo "nlink between: $(stat -c %h $dir)"
4948         local found=$(ls -U $dir | wc -l)
4949         [ $found -ne $left ] &&
4950                 error "can't find subdirs: found only $found, expected $left"
4951
4952         unlinkmany -d $dir/d $delete $left ||
4953                 error "unlink of second $left subdirs failed"
4954         # regardless of whether the backing filesystem tracks nlink accurately
4955         # or not, the nlink count shouldn't be more than "." and ".." here
4956         local after=$(stat -c %h $dir)
4957         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4958                 echo "nlink after: $after"
4959
4960         cleanup_print_lfs_df
4961 }
4962 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4963
4964 test_51d() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4967
4968         test_mkdir $DIR/$tdir
4969         createmany -o $DIR/$tdir/t- 1000
4970         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4971         for N in $(seq 0 $((OSTCOUNT - 1))); do
4972                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4973                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4974                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4975                         '($1 == '$N') { objs += 1 } \
4976                         END { printf("%0.0f", objs) }')
4977                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4978         done
4979         unlinkmany $DIR/$tdir/t- 1000
4980
4981         NLAST=0
4982         for N in $(seq 1 $((OSTCOUNT - 1))); do
4983                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4984                         error "OST $N has less objects vs OST $NLAST" \
4985                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4986                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4987                         error "OST $N has less objects vs OST $NLAST" \
4988                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4989
4990                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4991                         error "OST $N has less #0 objects vs OST $NLAST" \
4992                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4993                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4994                         error "OST $N has less #0 objects vs OST $NLAST" \
4995                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4996                 NLAST=$N
4997         done
4998         rm -f $TMP/$tfile
4999 }
5000 run_test 51d "check object distribution"
5001
5002 test_51e() {
5003         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5004                 skip_env "ldiskfs only test"
5005         fi
5006
5007         test_mkdir -c1 $DIR/$tdir
5008         test_mkdir -c1 $DIR/$tdir/d0
5009
5010         touch $DIR/$tdir/d0/foo
5011         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5012                 error "file exceed 65000 nlink limit!"
5013         unlinkmany $DIR/$tdir/d0/f- 65001
5014         return 0
5015 }
5016 run_test 51e "check file nlink limit"
5017
5018 test_51f() {
5019         test_mkdir $DIR/$tdir
5020
5021         local max=100000
5022         local ulimit_old=$(ulimit -n)
5023         local spare=20 # number of spare fd's for scripts/libraries, etc.
5024         local mdt=$($LFS getstripe -m $DIR/$tdir)
5025         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5026
5027         echo "MDT$mdt numfree=$numfree, max=$max"
5028         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5029         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5030                 while ! ulimit -n $((numfree + spare)); do
5031                         numfree=$((numfree * 3 / 4))
5032                 done
5033                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5034         else
5035                 echo "left ulimit at $ulimit_old"
5036         fi
5037
5038         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5039                 unlinkmany $DIR/$tdir/f $numfree
5040                 error "create+open $numfree files in $DIR/$tdir failed"
5041         }
5042         ulimit -n $ulimit_old
5043
5044         # if createmany exits at 120s there will be fewer than $numfree files
5045         unlinkmany $DIR/$tdir/f $numfree || true
5046 }
5047 run_test 51f "check many open files limit"
5048
5049 test_52a() {
5050         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5051         test_mkdir $DIR/$tdir
5052         touch $DIR/$tdir/foo
5053         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5054         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5055         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5056         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5057         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5058                                         error "link worked"
5059         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5060         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5061         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5062                                                      error "lsattr"
5063         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5064         cp -r $DIR/$tdir $TMP/
5065         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5066 }
5067 run_test 52a "append-only flag test (should return errors)"
5068
5069 test_52b() {
5070         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5071         test_mkdir $DIR/$tdir
5072         touch $DIR/$tdir/foo
5073         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5074         cat test > $DIR/$tdir/foo && error "cat test worked"
5075         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5076         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5077         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5078                                         error "link worked"
5079         echo foo >> $DIR/$tdir/foo && error "echo worked"
5080         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5081         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5082         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5083         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5084                                                         error "lsattr"
5085         chattr -i $DIR/$tdir/foo || error "chattr failed"
5086
5087         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5088 }
5089 run_test 52b "immutable flag test (should return errors) ======="
5090
5091 test_53() {
5092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5093         remote_mds_nodsh && skip "remote MDS with nodsh"
5094         remote_ost_nodsh && skip "remote OST with nodsh"
5095
5096         local param
5097         local param_seq
5098         local ostname
5099         local mds_last
5100         local mds_last_seq
5101         local ost_last
5102         local ost_last_seq
5103         local ost_last_id
5104         local ostnum
5105         local node
5106         local found=false
5107         local support_last_seq=true
5108
5109         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5110                 support_last_seq=false
5111
5112         # only test MDT0000
5113         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5114         local value
5115         for value in $(do_facet $SINGLEMDS \
5116                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5117                 param=$(echo ${value[0]} | cut -d "=" -f1)
5118                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5119
5120                 if $support_last_seq; then
5121                         param_seq=$(echo $param |
5122                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5123                         mds_last_seq=$(do_facet $SINGLEMDS \
5124                                        $LCTL get_param -n $param_seq)
5125                 fi
5126                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5127
5128                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5129                 node=$(facet_active_host ost$((ostnum+1)))
5130                 param="obdfilter.$ostname.last_id"
5131                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5132                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5133                         ost_last_id=$ost_last
5134
5135                         if $support_last_seq; then
5136                                 ost_last_id=$(echo $ost_last |
5137                                               awk -F':' '{print $2}' |
5138                                               sed -e "s/^0x//g")
5139                                 ost_last_seq=$(echo $ost_last |
5140                                                awk -F':' '{print $1}')
5141                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5142                         fi
5143
5144                         if [[ $ost_last_id != $mds_last ]]; then
5145                                 error "$ost_last_id != $mds_last"
5146                         else
5147                                 found=true
5148                                 break
5149                         fi
5150                 done
5151         done
5152         $found || error "can not match last_seq/last_id for $mdtosc"
5153         return 0
5154 }
5155 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5156
5157 test_54a() {
5158         perl -MSocket -e ';' || skip "no Socket perl module installed"
5159
5160         $SOCKETSERVER $DIR/socket ||
5161                 error "$SOCKETSERVER $DIR/socket failed: $?"
5162         $SOCKETCLIENT $DIR/socket ||
5163                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5164         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5165 }
5166 run_test 54a "unix domain socket test =========================="
5167
5168 test_54b() {
5169         f="$DIR/f54b"
5170         mknod $f c 1 3
5171         chmod 0666 $f
5172         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5173 }
5174 run_test 54b "char device works in lustre ======================"
5175
5176 find_loop_dev() {
5177         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5178         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5179         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5180
5181         for i in $(seq 3 7); do
5182                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5183                 LOOPDEV=$LOOPBASE$i
5184                 LOOPNUM=$i
5185                 break
5186         done
5187 }
5188
5189 cleanup_54c() {
5190         local rc=0
5191         loopdev="$DIR/loop54c"
5192
5193         trap 0
5194         $UMOUNT $DIR/$tdir || rc=$?
5195         losetup -d $loopdev || true
5196         losetup -d $LOOPDEV || true
5197         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5198         return $rc
5199 }
5200
5201 test_54c() {
5202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5203
5204         loopdev="$DIR/loop54c"
5205
5206         find_loop_dev
5207         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5208         trap cleanup_54c EXIT
5209         mknod $loopdev b 7 $LOOPNUM
5210         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5211         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5212         losetup $loopdev $DIR/$tfile ||
5213                 error "can't set up $loopdev for $DIR/$tfile"
5214         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5215         test_mkdir $DIR/$tdir
5216         mount -t ext2 $loopdev $DIR/$tdir ||
5217                 error "error mounting $loopdev on $DIR/$tdir"
5218         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5219                 error "dd write"
5220         df $DIR/$tdir
5221         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5222                 error "dd read"
5223         cleanup_54c
5224 }
5225 run_test 54c "block device works in lustre ====================="
5226
5227 test_54d() {
5228         f="$DIR/f54d"
5229         string="aaaaaa"
5230         mknod $f p
5231         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5232 }
5233 run_test 54d "fifo device works in lustre ======================"
5234
5235 test_54e() {
5236         f="$DIR/f54e"
5237         string="aaaaaa"
5238         cp -aL /dev/console $f
5239         echo $string > $f || error "echo $string to $f failed"
5240 }
5241 run_test 54e "console/tty device works in lustre ======================"
5242
5243 test_56a() {
5244         local numfiles=3
5245         local dir=$DIR/$tdir
5246
5247         rm -rf $dir
5248         test_mkdir -p $dir/dir
5249         for i in $(seq $numfiles); do
5250                 touch $dir/file$i
5251                 touch $dir/dir/file$i
5252         done
5253
5254         local numcomp=$($LFS getstripe --component-count $dir)
5255
5256         [[ $numcomp == 0 ]] && numcomp=1
5257
5258         # test lfs getstripe with --recursive
5259         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5260
5261         [[ $filenum -eq $((numfiles * 2)) ]] ||
5262                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5263         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5264         [[ $filenum -eq $numfiles ]] ||
5265                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5266         echo "$LFS getstripe showed obdidx or l_ost_idx"
5267
5268         # test lfs getstripe with file instead of dir
5269         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5270         [[ $filenum -eq 1 ]] ||
5271                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5272         echo "$LFS getstripe file1 passed"
5273
5274         #test lfs getstripe with --verbose
5275         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5276         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5277                 error "$LFS getstripe --verbose $dir: "\
5278                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5279         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5280                 error "$LFS getstripe $dir: showed lmm_magic"
5281
5282         #test lfs getstripe with -v prints lmm_fid
5283         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5284         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5285                 error "$LFS getstripe -v $dir: "\
5286                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5287         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5288                 error "$LFS getstripe $dir: showed lmm_fid by default"
5289         echo "$LFS getstripe --verbose passed"
5290
5291         #check for FID information
5292         local fid1=$($LFS getstripe --fid $dir/file1)
5293         local fid2=$($LFS getstripe --verbose $dir/file1 |
5294                      awk '/lmm_fid: / { print $2; exit; }')
5295         local fid3=$($LFS path2fid $dir/file1)
5296
5297         [ "$fid1" != "$fid2" ] &&
5298                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5299         [ "$fid1" != "$fid3" ] &&
5300                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5301         echo "$LFS getstripe --fid passed"
5302
5303         #test lfs getstripe with --obd
5304         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5305                 error "$LFS getstripe --obd wrong_uuid: should return error"
5306
5307         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5308
5309         local ostidx=1
5310         local obduuid=$(ostuuid_from_index $ostidx)
5311         local found=$($LFS getstripe -r --obd $obduuid $dir |
5312                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5313
5314         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5315         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5316                 ((filenum--))
5317         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5318                 ((filenum--))
5319
5320         [[ $found -eq $filenum ]] ||
5321                 error "$LFS getstripe --obd: found $found expect $filenum"
5322         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5323                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5324                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5325                 error "$LFS getstripe --obd: should not show file on other obd"
5326         echo "$LFS getstripe --obd passed"
5327 }
5328 run_test 56a "check $LFS getstripe"
5329
5330 test_56b() {
5331         local dir=$DIR/$tdir
5332         local numdirs=3
5333
5334         test_mkdir $dir
5335         for i in $(seq $numdirs); do
5336                 test_mkdir $dir/dir$i
5337         done
5338
5339         # test lfs getdirstripe default mode is non-recursion, which is
5340         # different from lfs getstripe
5341         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5342
5343         [[ $dircnt -eq 1 ]] ||
5344                 error "$LFS getdirstripe: found $dircnt, not 1"
5345         dircnt=$($LFS getdirstripe --recursive $dir |
5346                 grep -c lmv_stripe_count)
5347         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5348                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5349 }
5350 run_test 56b "check $LFS getdirstripe"
5351
5352 test_56c() {
5353         remote_ost_nodsh && skip "remote OST with nodsh"
5354
5355         local ost_idx=0
5356         local ost_name=$(ostname_from_index $ost_idx)
5357         local old_status=$(ost_dev_status $ost_idx)
5358
5359         [[ -z "$old_status" ]] ||
5360                 skip_env "OST $ost_name is in $old_status status"
5361
5362         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5363         sleep_maxage
5364
5365         local new_status=$(ost_dev_status $ost_idx)
5366
5367         [[ "$new_status" = "D" ]] ||
5368                 error "OST $ost_name is in status of '$new_status', not 'D'"
5369
5370         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5371         sleep_maxage
5372
5373         new_status=$(ost_dev_status $ost_idx)
5374         [[ -z "$new_status" ]] ||
5375                 error "OST $ost_name is in status of '$new_status', not ''"
5376 }
5377 run_test 56c "check 'lfs df' showing device status"
5378
5379 NUMFILES=3
5380 NUMDIRS=3
5381 setup_56() {
5382         local local_tdir="$1"
5383         local local_numfiles="$2"
5384         local local_numdirs="$3"
5385         local dir_params="$4"
5386         local dir_stripe_params="$5"
5387
5388         if [ ! -d "$local_tdir" ] ; then
5389                 test_mkdir -p $dir_stripe_params $local_tdir
5390                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5391                 for i in $(seq $local_numfiles) ; do
5392                         touch $local_tdir/file$i
5393                 done
5394                 for i in $(seq $local_numdirs) ; do
5395                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5396                         for j in $(seq $local_numfiles) ; do
5397                                 touch $local_tdir/dir$i/file$j
5398                         done
5399                 done
5400         fi
5401 }
5402
5403 setup_56_special() {
5404         local local_tdir=$1
5405         local local_numfiles=$2
5406         local local_numdirs=$3
5407
5408         setup_56 $local_tdir $local_numfiles $local_numdirs
5409
5410         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5411                 for i in $(seq $local_numfiles) ; do
5412                         mknod $local_tdir/loop${i}b b 7 $i
5413                         mknod $local_tdir/null${i}c c 1 3
5414                         ln -s $local_tdir/file1 $local_tdir/link${i}
5415                 done
5416                 for i in $(seq $local_numdirs) ; do
5417                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5418                         mknod $local_tdir/dir$i/null${i}c c 1 3
5419                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5420                 done
5421         fi
5422 }
5423
5424 test_56g() {
5425         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5426         local expected=$(($NUMDIRS + 2))
5427
5428         setup_56 $dir $NUMFILES $NUMDIRS
5429
5430         # test lfs find with -name
5431         for i in $(seq $NUMFILES) ; do
5432                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5433
5434                 [ $nums -eq $expected ] ||
5435                         error "lfs find -name '*$i' $dir wrong: "\
5436                               "found $nums, expected $expected"
5437         done
5438 }
5439 run_test 56g "check lfs find -name"
5440
5441 test_56h() {
5442         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5443         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5444
5445         setup_56 $dir $NUMFILES $NUMDIRS
5446
5447         # test lfs find with ! -name
5448         for i in $(seq $NUMFILES) ; do
5449                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5450
5451                 [ $nums -eq $expected ] ||
5452                         error "lfs find ! -name '*$i' $dir wrong: "\
5453                               "found $nums, expected $expected"
5454         done
5455 }
5456 run_test 56h "check lfs find ! -name"
5457
5458 test_56i() {
5459         local dir=$DIR/$tdir
5460
5461         test_mkdir $dir
5462
5463         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5464         local out=$($cmd)
5465
5466         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5467 }
5468 run_test 56i "check 'lfs find -ost UUID' skips directories"
5469
5470 test_56j() {
5471         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5472
5473         setup_56_special $dir $NUMFILES $NUMDIRS
5474
5475         local expected=$((NUMDIRS + 1))
5476         local cmd="$LFS find -type d $dir"
5477         local nums=$($cmd | wc -l)
5478
5479         [ $nums -eq $expected ] ||
5480                 error "'$cmd' wrong: found $nums, expected $expected"
5481 }
5482 run_test 56j "check lfs find -type d"
5483
5484 test_56k() {
5485         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5486
5487         setup_56_special $dir $NUMFILES $NUMDIRS
5488
5489         local expected=$(((NUMDIRS + 1) * NUMFILES))
5490         local cmd="$LFS find -type f $dir"
5491         local nums=$($cmd | wc -l)
5492
5493         [ $nums -eq $expected ] ||
5494                 error "'$cmd' wrong: found $nums, expected $expected"
5495 }
5496 run_test 56k "check lfs find -type f"
5497
5498 test_56l() {
5499         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5500
5501         setup_56_special $dir $NUMFILES $NUMDIRS
5502
5503         local expected=$((NUMDIRS + NUMFILES))
5504         local cmd="$LFS find -type b $dir"
5505         local nums=$($cmd | wc -l)
5506
5507         [ $nums -eq $expected ] ||
5508                 error "'$cmd' wrong: found $nums, expected $expected"
5509 }
5510 run_test 56l "check lfs find -type b"
5511
5512 test_56m() {
5513         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5514
5515         setup_56_special $dir $NUMFILES $NUMDIRS
5516
5517         local expected=$((NUMDIRS + NUMFILES))
5518         local cmd="$LFS find -type c $dir"
5519         local nums=$($cmd | wc -l)
5520         [ $nums -eq $expected ] ||
5521                 error "'$cmd' wrong: found $nums, expected $expected"
5522 }
5523 run_test 56m "check lfs find -type c"
5524
5525 test_56n() {
5526         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5527         setup_56_special $dir $NUMFILES $NUMDIRS
5528
5529         local expected=$((NUMDIRS + NUMFILES))
5530         local cmd="$LFS find -type l $dir"
5531         local nums=$($cmd | wc -l)
5532
5533         [ $nums -eq $expected ] ||
5534                 error "'$cmd' wrong: found $nums, expected $expected"
5535 }
5536 run_test 56n "check lfs find -type l"
5537
5538 test_56o() {
5539         local dir=$DIR/$tdir
5540
5541         setup_56 $dir $NUMFILES $NUMDIRS
5542         utime $dir/file1 > /dev/null || error "utime (1)"
5543         utime $dir/file2 > /dev/null || error "utime (2)"
5544         utime $dir/dir1 > /dev/null || error "utime (3)"
5545         utime $dir/dir2 > /dev/null || error "utime (4)"
5546         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5547         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5548
5549         local expected=4
5550         local nums=$($LFS find -mtime +0 $dir | wc -l)
5551
5552         [ $nums -eq $expected ] ||
5553                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5554
5555         expected=12
5556         cmd="$LFS find -mtime 0 $dir"
5557         nums=$($cmd | wc -l)
5558         [ $nums -eq $expected ] ||
5559                 error "'$cmd' wrong: found $nums, expected $expected"
5560 }
5561 run_test 56o "check lfs find -mtime for old files"
5562
5563 test_56ob() {
5564         local dir=$DIR/$tdir
5565         local expected=1
5566         local count=0
5567
5568         # just to make sure there is something that won't be found
5569         test_mkdir $dir
5570         touch $dir/$tfile.now
5571
5572         for age in year week day hour min; do
5573                 count=$((count + 1))
5574
5575                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5576                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5577                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5578
5579                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5580                 local nums=$($cmd | wc -l)
5581                 [ $nums -eq $expected ] ||
5582                         error "'$cmd' wrong: found $nums, expected $expected"
5583
5584                 cmd="$LFS find $dir -atime $count${age:0:1}"
5585                 nums=$($cmd | wc -l)
5586                 [ $nums -eq $expected ] ||
5587                         error "'$cmd' wrong: found $nums, expected $expected"
5588         done
5589
5590         sleep 2
5591         cmd="$LFS find $dir -ctime +1s -type f"
5592         nums=$($cmd | wc -l)
5593         (( $nums == $count * 2 + 1)) ||
5594                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5595 }
5596 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5597
5598 test_56p() {
5599         [ $RUNAS_ID -eq $UID ] &&
5600                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5601
5602         local dir=$DIR/$tdir
5603
5604         setup_56 $dir $NUMFILES $NUMDIRS
5605         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5606
5607         local expected=$NUMFILES
5608         local cmd="$LFS find -uid $RUNAS_ID $dir"
5609         local nums=$($cmd | wc -l)
5610
5611         [ $nums -eq $expected ] ||
5612                 error "'$cmd' wrong: found $nums, expected $expected"
5613
5614         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5615         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5616         nums=$($cmd | wc -l)
5617         [ $nums -eq $expected ] ||
5618                 error "'$cmd' wrong: found $nums, expected $expected"
5619 }
5620 run_test 56p "check lfs find -uid and ! -uid"
5621
5622 test_56q() {
5623         [ $RUNAS_ID -eq $UID ] &&
5624                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5625
5626         local dir=$DIR/$tdir
5627
5628         setup_56 $dir $NUMFILES $NUMDIRS
5629         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5630
5631         local expected=$NUMFILES
5632         local cmd="$LFS find -gid $RUNAS_GID $dir"
5633         local nums=$($cmd | wc -l)
5634
5635         [ $nums -eq $expected ] ||
5636                 error "'$cmd' wrong: found $nums, expected $expected"
5637
5638         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5639         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5640         nums=$($cmd | wc -l)
5641         [ $nums -eq $expected ] ||
5642                 error "'$cmd' wrong: found $nums, expected $expected"
5643 }
5644 run_test 56q "check lfs find -gid and ! -gid"
5645
5646 test_56r() {
5647         local dir=$DIR/$tdir
5648
5649         setup_56 $dir $NUMFILES $NUMDIRS
5650
5651         local expected=12
5652         local cmd="$LFS find -size 0 -type f $dir"
5653         local nums=$($cmd | wc -l)
5654
5655         [ $nums -eq $expected ] ||
5656                 error "'$cmd' wrong: found $nums, expected $expected"
5657         expected=0
5658         cmd="$LFS find ! -size 0 -type f $dir"
5659         nums=$($cmd | wc -l)
5660         [ $nums -eq $expected ] ||
5661                 error "'$cmd' wrong: found $nums, expected $expected"
5662         echo "test" > $dir/$tfile
5663         echo "test2" > $dir/$tfile.2 && sync
5664         expected=1
5665         cmd="$LFS find -size 5 -type f $dir"
5666         nums=$($cmd | wc -l)
5667         [ $nums -eq $expected ] ||
5668                 error "'$cmd' wrong: found $nums, expected $expected"
5669         expected=1
5670         cmd="$LFS find -size +5 -type f $dir"
5671         nums=$($cmd | wc -l)
5672         [ $nums -eq $expected ] ||
5673                 error "'$cmd' wrong: found $nums, expected $expected"
5674         expected=2
5675         cmd="$LFS find -size +0 -type f $dir"
5676         nums=$($cmd | wc -l)
5677         [ $nums -eq $expected ] ||
5678                 error "'$cmd' wrong: found $nums, expected $expected"
5679         expected=2
5680         cmd="$LFS find ! -size -5 -type f $dir"
5681         nums=$($cmd | wc -l)
5682         [ $nums -eq $expected ] ||
5683                 error "'$cmd' wrong: found $nums, expected $expected"
5684         expected=12
5685         cmd="$LFS find -size -5 -type f $dir"
5686         nums=$($cmd | wc -l)
5687         [ $nums -eq $expected ] ||
5688                 error "'$cmd' wrong: found $nums, expected $expected"
5689 }
5690 run_test 56r "check lfs find -size works"
5691
5692 test_56s() { # LU-611 #LU-9369
5693         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5694
5695         local dir=$DIR/$tdir
5696         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5697
5698         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5699         for i in $(seq $NUMDIRS); do
5700                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5701         done
5702
5703         local expected=$NUMDIRS
5704         local cmd="$LFS find -c $OSTCOUNT $dir"
5705         local nums=$($cmd | wc -l)
5706
5707         [ $nums -eq $expected ] || {
5708                 $LFS getstripe -R $dir
5709                 error "'$cmd' wrong: found $nums, expected $expected"
5710         }
5711
5712         expected=$((NUMDIRS + onestripe))
5713         cmd="$LFS find -stripe-count +0 -type f $dir"
5714         nums=$($cmd | wc -l)
5715         [ $nums -eq $expected ] || {
5716                 $LFS getstripe -R $dir
5717                 error "'$cmd' wrong: found $nums, expected $expected"
5718         }
5719
5720         expected=$onestripe
5721         cmd="$LFS find -stripe-count 1 -type f $dir"
5722         nums=$($cmd | wc -l)
5723         [ $nums -eq $expected ] || {
5724                 $LFS getstripe -R $dir
5725                 error "'$cmd' wrong: found $nums, expected $expected"
5726         }
5727
5728         cmd="$LFS find -stripe-count -2 -type f $dir"
5729         nums=$($cmd | wc -l)
5730         [ $nums -eq $expected ] || {
5731                 $LFS getstripe -R $dir
5732                 error "'$cmd' wrong: found $nums, expected $expected"
5733         }
5734
5735         expected=0
5736         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5737         nums=$($cmd | wc -l)
5738         [ $nums -eq $expected ] || {
5739                 $LFS getstripe -R $dir
5740                 error "'$cmd' wrong: found $nums, expected $expected"
5741         }
5742 }
5743 run_test 56s "check lfs find -stripe-count works"
5744
5745 test_56t() { # LU-611 #LU-9369
5746         local dir=$DIR/$tdir
5747
5748         setup_56 $dir 0 $NUMDIRS
5749         for i in $(seq $NUMDIRS); do
5750                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5751         done
5752
5753         local expected=$NUMDIRS
5754         local cmd="$LFS find -S 8M $dir"
5755         local nums=$($cmd | wc -l)
5756
5757         [ $nums -eq $expected ] || {
5758                 $LFS getstripe -R $dir
5759                 error "'$cmd' wrong: found $nums, expected $expected"
5760         }
5761         rm -rf $dir
5762
5763         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5764
5765         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5766
5767         expected=$(((NUMDIRS + 1) * NUMFILES))
5768         cmd="$LFS find -stripe-size 512k -type f $dir"
5769         nums=$($cmd | wc -l)
5770         [ $nums -eq $expected ] ||
5771                 error "'$cmd' wrong: found $nums, expected $expected"
5772
5773         cmd="$LFS find -stripe-size +320k -type f $dir"
5774         nums=$($cmd | wc -l)
5775         [ $nums -eq $expected ] ||
5776                 error "'$cmd' wrong: found $nums, expected $expected"
5777
5778         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5779         cmd="$LFS find -stripe-size +200k -type f $dir"
5780         nums=$($cmd | wc -l)
5781         [ $nums -eq $expected ] ||
5782                 error "'$cmd' wrong: found $nums, expected $expected"
5783
5784         cmd="$LFS find -stripe-size -640k -type f $dir"
5785         nums=$($cmd | wc -l)
5786         [ $nums -eq $expected ] ||
5787                 error "'$cmd' wrong: found $nums, expected $expected"
5788
5789         expected=4
5790         cmd="$LFS find -stripe-size 256k -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         cmd="$LFS find -stripe-size -320k -type f $dir"
5796         nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799
5800         expected=0
5801         cmd="$LFS find -stripe-size 1024k -type f $dir"
5802         nums=$($cmd | wc -l)
5803         [ $nums -eq $expected ] ||
5804                 error "'$cmd' wrong: found $nums, expected $expected"
5805 }
5806 run_test 56t "check lfs find -stripe-size works"
5807
5808 test_56u() { # LU-611
5809         local dir=$DIR/$tdir
5810
5811         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5812
5813         if [[ $OSTCOUNT -gt 1 ]]; then
5814                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5815                 onestripe=4
5816         else
5817                 onestripe=0
5818         fi
5819
5820         local expected=$(((NUMDIRS + 1) * NUMFILES))
5821         local cmd="$LFS find -stripe-index 0 -type f $dir"
5822         local nums=$($cmd | wc -l)
5823
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=$onestripe
5828         cmd="$LFS find -stripe-index 1 -type f $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832
5833         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5834         nums=$($cmd | wc -l)
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837
5838         expected=0
5839         # This should produce an error and not return any files
5840         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5841         nums=$($cmd 2>/dev/null | wc -l)
5842         [ $nums -eq $expected ] ||
5843                 error "'$cmd' wrong: found $nums, expected $expected"
5844
5845         if [[ $OSTCOUNT -gt 1 ]]; then
5846                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5847                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5848                 nums=$($cmd | wc -l)
5849                 [ $nums -eq $expected ] ||
5850                         error "'$cmd' wrong: found $nums, expected $expected"
5851         fi
5852 }
5853 run_test 56u "check lfs find -stripe-index works"
5854
5855 test_56v() {
5856         local mdt_idx=0
5857         local dir=$DIR/$tdir
5858
5859         setup_56 $dir $NUMFILES $NUMDIRS
5860
5861         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5862         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5863
5864         for file in $($LFS find -m $UUID $dir); do
5865                 file_midx=$($LFS getstripe -m $file)
5866                 [ $file_midx -eq $mdt_idx ] ||
5867                         error "lfs find -m $UUID != getstripe -m $file_midx"
5868         done
5869 }
5870 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5871
5872 test_56w() {
5873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875
5876         local dir=$DIR/$tdir
5877
5878         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5879
5880         local stripe_size=$($LFS getstripe -S -d $dir) ||
5881                 error "$LFS getstripe -S -d $dir failed"
5882         stripe_size=${stripe_size%% *}
5883
5884         local file_size=$((stripe_size * OSTCOUNT))
5885         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5886         local required_space=$((file_num * file_size))
5887         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5888                            head -n1)
5889         [[ $free_space -le $((required_space / 1024)) ]] &&
5890                 skip_env "need $required_space, have $free_space kbytes"
5891
5892         local dd_bs=65536
5893         local dd_count=$((file_size / dd_bs))
5894
5895         # write data into the files
5896         local i
5897         local j
5898         local file
5899
5900         for i in $(seq $NUMFILES); do
5901                 file=$dir/file$i
5902                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5903                         error "write data into $file failed"
5904         done
5905         for i in $(seq $NUMDIRS); do
5906                 for j in $(seq $NUMFILES); do
5907                         file=$dir/dir$i/file$j
5908                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5909                                 error "write data into $file failed"
5910                 done
5911         done
5912
5913         # $LFS_MIGRATE will fail if hard link migration is unsupported
5914         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5915                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5916                         error "creating links to $dir/dir1/file1 failed"
5917         fi
5918
5919         local expected=-1
5920
5921         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5922
5923         # lfs_migrate file
5924         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5925
5926         echo "$cmd"
5927         eval $cmd || error "$cmd failed"
5928
5929         check_stripe_count $dir/file1 $expected
5930
5931         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5932         then
5933                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5934                 # OST 1 if it is on OST 0. This file is small enough to
5935                 # be on only one stripe.
5936                 file=$dir/migr_1_ost
5937                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5938                         error "write data into $file failed"
5939                 local obdidx=$($LFS getstripe -i $file)
5940                 local oldmd5=$(md5sum $file)
5941                 local newobdidx=0
5942
5943                 [[ $obdidx -eq 0 ]] && newobdidx=1
5944                 cmd="$LFS migrate -i $newobdidx $file"
5945                 echo $cmd
5946                 eval $cmd || error "$cmd failed"
5947
5948                 local realobdix=$($LFS getstripe -i $file)
5949                 local newmd5=$(md5sum $file)
5950
5951                 [[ $newobdidx -ne $realobdix ]] &&
5952                         error "new OST is different (was=$obdidx, "\
5953                               "wanted=$newobdidx, got=$realobdix)"
5954                 [[ "$oldmd5" != "$newmd5" ]] &&
5955                         error "md5sum differ: $oldmd5, $newmd5"
5956         fi
5957
5958         # lfs_migrate dir
5959         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5960         echo "$cmd"
5961         eval $cmd || error "$cmd failed"
5962
5963         for j in $(seq $NUMFILES); do
5964                 check_stripe_count $dir/dir1/file$j $expected
5965         done
5966
5967         # lfs_migrate works with lfs find
5968         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5969              $LFS_MIGRATE -y -c $expected"
5970         echo "$cmd"
5971         eval $cmd || error "$cmd failed"
5972
5973         for i in $(seq 2 $NUMFILES); do
5974                 check_stripe_count $dir/file$i $expected
5975         done
5976         for i in $(seq 2 $NUMDIRS); do
5977                 for j in $(seq $NUMFILES); do
5978                 check_stripe_count $dir/dir$i/file$j $expected
5979                 done
5980         done
5981 }
5982 run_test 56w "check lfs_migrate -c stripe_count works"
5983
5984 test_56wb() {
5985         local file1=$DIR/$tdir/file1
5986         local create_pool=false
5987         local initial_pool=$($LFS getstripe -p $DIR)
5988         local pool_list=()
5989         local pool=""
5990
5991         echo -n "Creating test dir..."
5992         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5993         echo "done."
5994
5995         echo -n "Creating test file..."
5996         touch $file1 || error "cannot create file"
5997         echo "done."
5998
5999         echo -n "Detecting existing pools..."
6000         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6001
6002         if [ ${#pool_list[@]} -gt 0 ]; then
6003                 echo "${pool_list[@]}"
6004                 for thispool in "${pool_list[@]}"; do
6005                         if [[ -z "$initial_pool" ||
6006                               "$initial_pool" != "$thispool" ]]; then
6007                                 pool="$thispool"
6008                                 echo "Using existing pool '$pool'"
6009                                 break
6010                         fi
6011                 done
6012         else
6013                 echo "none detected."
6014         fi
6015         if [ -z "$pool" ]; then
6016                 pool=${POOL:-testpool}
6017                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6018                 echo -n "Creating pool '$pool'..."
6019                 create_pool=true
6020                 pool_add $pool &> /dev/null ||
6021                         error "pool_add failed"
6022                 echo "done."
6023
6024                 echo -n "Adding target to pool..."
6025                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6026                         error "pool_add_targets failed"
6027                 echo "done."
6028         fi
6029
6030         echo -n "Setting pool using -p option..."
6031         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6032                 error "migrate failed rc = $?"
6033         echo "done."
6034
6035         echo -n "Verifying test file is in pool after migrating..."
6036         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6037                 error "file was not migrated to pool $pool"
6038         echo "done."
6039
6040         echo -n "Removing test file from pool '$pool'..."
6041         $LFS migrate $file1 &> /dev/null ||
6042                 error "cannot remove from pool"
6043         [ "$($LFS getstripe -p $file1)" ] &&
6044                 error "pool still set"
6045         echo "done."
6046
6047         echo -n "Setting pool using --pool option..."
6048         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6049                 error "migrate failed rc = $?"
6050         echo "done."
6051
6052         # Clean up
6053         rm -f $file1
6054         if $create_pool; then
6055                 destroy_test_pools 2> /dev/null ||
6056                         error "destroy test pools failed"
6057         fi
6058 }
6059 run_test 56wb "check lfs_migrate pool support"
6060
6061 test_56wc() {
6062         local file1="$DIR/$tdir/file1"
6063
6064         echo -n "Creating test dir..."
6065         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6066         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6067         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6068                 error "cannot set stripe"
6069         echo "done"
6070
6071         echo -n "Setting initial stripe for test file..."
6072         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6073                 error "cannot set stripe"
6074         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6075                 error "stripe size not set"
6076         echo "done."
6077
6078         # File currently set to -S 512K -c 1
6079
6080         # Ensure -c and -S options are rejected when -R is set
6081         echo -n "Verifying incompatible options are detected..."
6082         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6083                 error "incompatible -c and -R options not detected"
6084         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6085                 error "incompatible -S and -R options not detected"
6086         echo "done."
6087
6088         # Ensure unrecognized options are passed through to 'lfs migrate'
6089         echo -n "Verifying -S option is passed through to lfs migrate..."
6090         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6091                 error "migration failed"
6092         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6093                 error "file was not restriped"
6094         echo "done."
6095
6096         # File currently set to -S 1M -c 1
6097
6098         # Ensure long options are supported
6099         echo -n "Verifying long options supported..."
6100         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6101                 error "long option without argument not supported"
6102         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6103                 error "long option with argument not supported"
6104         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6105                 error "file not restriped with --stripe-size option"
6106         echo "done."
6107
6108         # File currently set to -S 512K -c 1
6109
6110         if [ "$OSTCOUNT" -gt 1 ]; then
6111                 echo -n "Verifying explicit stripe count can be set..."
6112                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6113                         error "migrate failed"
6114                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6115                         error "file not restriped to explicit count"
6116                 echo "done."
6117         fi
6118
6119         # File currently set to -S 512K -c 1 or -S 512K -c 2
6120
6121         # Ensure parent striping is used if -R is set, and no stripe
6122         # count or size is specified
6123         echo -n "Setting stripe for parent directory..."
6124         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6125                 error "cannot set stripe"
6126         echo "done."
6127
6128         echo -n "Verifying restripe option uses parent stripe settings..."
6129         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6130                 error "migrate failed"
6131         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6132                 error "file not restriped to parent settings"
6133         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6134                 error "file not restriped to parent settings"
6135         echo "done."
6136
6137         # File currently set to -S 1M -c 1
6138
6139         # Ensure striping is preserved if -R is not set, and no stripe
6140         # count or size is specified
6141         echo -n "Verifying striping size preserved when not specified..."
6142         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6143         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6144                 error "cannot set stripe on parent directory"
6145         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6146                 error "migrate failed"
6147         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6148                 error "file was restriped"
6149         echo "done."
6150
6151         # Ensure file name properly detected when final option has no argument
6152         echo -n "Verifying file name properly detected..."
6153         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6154                 error "file name interpreted as option argument"
6155         echo "done."
6156
6157         # Clean up
6158         rm -f "$file1"
6159 }
6160 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6161
6162 test_56wd() {
6163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6164
6165         local file1=$DIR/$tdir/file1
6166
6167         echo -n "Creating test dir..."
6168         test_mkdir $DIR/$tdir || error "cannot create dir"
6169         echo "done."
6170
6171         echo -n "Creating test file..."
6172         touch $file1
6173         echo "done."
6174
6175         # Ensure 'lfs migrate' will fail by using a non-existent option,
6176         # and make sure rsync is not called to recover
6177         echo -n "Make sure --no-rsync option works..."
6178         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6179                 grep -q 'refusing to fall back to rsync' ||
6180                 error "rsync was called with --no-rsync set"
6181         echo "done."
6182
6183         # Ensure rsync is called without trying 'lfs migrate' first
6184         echo -n "Make sure --rsync option works..."
6185         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6186                 grep -q 'falling back to rsync' &&
6187                 error "lfs migrate was called with --rsync set"
6188         echo "done."
6189
6190         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6191         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6192                 grep -q 'at the same time' ||
6193                 error "--rsync and --no-rsync accepted concurrently"
6194         echo "done."
6195
6196         # Clean up
6197         rm -f $file1
6198 }
6199 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6200
6201 test_56x() {
6202         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6203         check_swap_layouts_support
6204
6205         local dir=$DIR/$tdir
6206         local ref1=/etc/passwd
6207         local file1=$dir/file1
6208
6209         test_mkdir $dir || error "creating dir $dir"
6210         $LFS setstripe -c 2 $file1
6211         cp $ref1 $file1
6212         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6213         stripe=$($LFS getstripe -c $file1)
6214         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6215         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6216
6217         # clean up
6218         rm -f $file1
6219 }
6220 run_test 56x "lfs migration support"
6221
6222 test_56xa() {
6223         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6224         check_swap_layouts_support
6225
6226         local dir=$DIR/$tdir/$testnum
6227
6228         test_mkdir -p $dir
6229
6230         local ref1=/etc/passwd
6231         local file1=$dir/file1
6232
6233         $LFS setstripe -c 2 $file1
6234         cp $ref1 $file1
6235         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6236
6237         local stripe=$($LFS getstripe -c $file1)
6238
6239         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6240         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6241
6242         # clean up
6243         rm -f $file1
6244 }
6245 run_test 56xa "lfs migration --block support"
6246
6247 check_migrate_links() {
6248         local dir="$1"
6249         local file1="$dir/file1"
6250         local begin="$2"
6251         local count="$3"
6252         local total_count=$(($begin + $count - 1))
6253         local symlink_count=10
6254         local uniq_count=10
6255
6256         if [ ! -f "$file1" ]; then
6257                 echo -n "creating initial file..."
6258                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6259                         error "cannot setstripe initial file"
6260                 echo "done"
6261
6262                 echo -n "creating symlinks..."
6263                 for s in $(seq 1 $symlink_count); do
6264                         ln -s "$file1" "$dir/slink$s" ||
6265                                 error "cannot create symlinks"
6266                 done
6267                 echo "done"
6268
6269                 echo -n "creating nonlinked files..."
6270                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6271                         error "cannot create nonlinked files"
6272                 echo "done"
6273         fi
6274
6275         # create hard links
6276         if [ ! -f "$dir/file$total_count" ]; then
6277                 echo -n "creating hard links $begin:$total_count..."
6278                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6279                         /dev/null || error "cannot create hard links"
6280                 echo "done"
6281         fi
6282
6283         echo -n "checking number of hard links listed in xattrs..."
6284         local fid=$($LFS getstripe -F "$file1")
6285         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6286
6287         echo "${#paths[*]}"
6288         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6289                         skip "hard link list has unexpected size, skipping test"
6290         fi
6291         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6292                         error "link names should exceed xattrs size"
6293         fi
6294
6295         echo -n "migrating files..."
6296         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6297         local rc=$?
6298         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6299         echo "done"
6300
6301         # make sure all links have been properly migrated
6302         echo -n "verifying files..."
6303         fid=$($LFS getstripe -F "$file1") ||
6304                 error "cannot get fid for file $file1"
6305         for i in $(seq 2 $total_count); do
6306                 local fid2=$($LFS getstripe -F $dir/file$i)
6307
6308                 [ "$fid2" == "$fid" ] ||
6309                         error "migrated hard link has mismatched FID"
6310         done
6311
6312         # make sure hard links were properly detected, and migration was
6313         # performed only once for the entire link set; nonlinked files should
6314         # also be migrated
6315         local actual=$(grep -c 'done' <<< "$migrate_out")
6316         local expected=$(($uniq_count + 1))
6317
6318         [ "$actual" -eq  "$expected" ] ||
6319                 error "hard links individually migrated ($actual != $expected)"
6320
6321         # make sure the correct number of hard links are present
6322         local hardlinks=$(stat -c '%h' "$file1")
6323
6324         [ $hardlinks -eq $total_count ] ||
6325                 error "num hard links $hardlinks != $total_count"
6326         echo "done"
6327
6328         return 0
6329 }
6330
6331 test_56xb() {
6332         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6333                 skip "Need MDS version at least 2.10.55"
6334
6335         local dir="$DIR/$tdir"
6336
6337         test_mkdir "$dir" || error "cannot create dir $dir"
6338
6339         echo "testing lfs migrate mode when all links fit within xattrs"
6340         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6341
6342         echo "testing rsync mode when all links fit within xattrs"
6343         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6344
6345         echo "testing lfs migrate mode when all links do not fit within xattrs"
6346         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6347
6348         echo "testing rsync mode when all links do not fit within xattrs"
6349         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6350
6351
6352         # clean up
6353         rm -rf $dir
6354 }
6355 run_test 56xb "lfs migration hard link support"
6356
6357 test_56xc() {
6358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6359
6360         local dir="$DIR/$tdir"
6361
6362         test_mkdir "$dir" || error "cannot create dir $dir"
6363
6364         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6365         echo -n "Setting initial stripe for 20MB test file..."
6366         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6367                 error "cannot setstripe 20MB file"
6368         echo "done"
6369         echo -n "Sizing 20MB test file..."
6370         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6371         echo "done"
6372         echo -n "Verifying small file autostripe count is 1..."
6373         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6374                 error "cannot migrate 20MB file"
6375         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6376                 error "cannot get stripe for $dir/20mb"
6377         [ $stripe_count -eq 1 ] ||
6378                 error "unexpected stripe count $stripe_count for 20MB file"
6379         rm -f "$dir/20mb"
6380         echo "done"
6381
6382         # Test 2: File is small enough to fit within the available space on
6383         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6384         # have at least an additional 1KB for each desired stripe for test 3
6385         echo -n "Setting stripe for 1GB test file..."
6386         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6387         echo "done"
6388         echo -n "Sizing 1GB test file..."
6389         # File size is 1GB + 3KB
6390         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6391         echo "done"
6392
6393         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6394         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6395         if (( avail > 524288 * OSTCOUNT )); then
6396                 echo -n "Migrating 1GB file..."
6397                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6398                         error "cannot migrate 1GB file"
6399                 echo "done"
6400                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6401                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6402                         error "cannot getstripe for 1GB file"
6403                 [ $stripe_count -eq 2 ] ||
6404                         error "unexpected stripe count $stripe_count != 2"
6405                 echo "done"
6406         fi
6407
6408         # Test 3: File is too large to fit within the available space on
6409         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6410         if [ $OSTCOUNT -ge 3 ]; then
6411                 # The required available space is calculated as
6412                 # file size (1GB + 3KB) / OST count (3).
6413                 local kb_per_ost=349526
6414
6415                 echo -n "Migrating 1GB file with limit..."
6416                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6417                         error "cannot migrate 1GB file with limit"
6418                 echo "done"
6419
6420                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6421                 echo -n "Verifying 1GB autostripe count with limited space..."
6422                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6423                         error "unexpected stripe count $stripe_count (min 3)"
6424                 echo "done"
6425         fi
6426
6427         # clean up
6428         rm -rf $dir
6429 }
6430 run_test 56xc "lfs migration autostripe"
6431
6432 test_56y() {
6433         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6434                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6435
6436         local res=""
6437         local dir=$DIR/$tdir
6438         local f1=$dir/file1
6439         local f2=$dir/file2
6440
6441         test_mkdir -p $dir || error "creating dir $dir"
6442         touch $f1 || error "creating std file $f1"
6443         $MULTIOP $f2 H2c || error "creating released file $f2"
6444
6445         # a directory can be raid0, so ask only for files
6446         res=$($LFS find $dir -L raid0 -type f | wc -l)
6447         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6448
6449         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6450         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6451
6452         # only files can be released, so no need to force file search
6453         res=$($LFS find $dir -L released)
6454         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6455
6456         res=$($LFS find $dir -type f \! -L released)
6457         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6458 }
6459 run_test 56y "lfs find -L raid0|released"
6460
6461 test_56z() { # LU-4824
6462         # This checks to make sure 'lfs find' continues after errors
6463         # There are two classes of errors that should be caught:
6464         # - If multiple paths are provided, all should be searched even if one
6465         #   errors out
6466         # - If errors are encountered during the search, it should not terminate
6467         #   early
6468         local dir=$DIR/$tdir
6469         local i
6470
6471         test_mkdir $dir
6472         for i in d{0..9}; do
6473                 test_mkdir $dir/$i
6474                 touch $dir/$i/$tfile
6475         done
6476         $LFS find $DIR/non_existent_dir $dir &&
6477                 error "$LFS find did not return an error"
6478         # Make a directory unsearchable. This should NOT be the last entry in
6479         # directory order.  Arbitrarily pick the 6th entry
6480         chmod 700 $($LFS find $dir -type d | sed '6!d')
6481
6482         $RUNAS $LFS find $DIR/non_existent $dir
6483         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6484
6485         # The user should be able to see 10 directories and 9 files
6486         (( count == 19 )) ||
6487                 error "$LFS find found $count != 19 entries after error"
6488 }
6489 run_test 56z "lfs find should continue after an error"
6490
6491 test_56aa() { # LU-5937
6492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6493
6494         local dir=$DIR/$tdir
6495
6496         mkdir $dir
6497         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6498
6499         createmany -o $dir/striped_dir/${tfile}- 1024
6500         local dirs=$($LFS find --size +8k $dir/)
6501
6502         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6503 }
6504 run_test 56aa "lfs find --size under striped dir"
6505
6506 test_56ab() { # LU-10705
6507         test_mkdir $DIR/$tdir
6508         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6509         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6510         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6511         # Flush writes to ensure valid blocks.  Need to be more thorough for
6512         # ZFS, since blocks are not allocated/returned to client immediately.
6513         sync_all_data
6514         wait_zfs_commit ost1 2
6515         cancel_lru_locks osc
6516         ls -ls $DIR/$tdir
6517
6518         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6519
6520         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6521
6522         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6523         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6524
6525         rm -f $DIR/$tdir/$tfile.[123]
6526 }
6527 run_test 56ab "lfs find --blocks"
6528
6529 test_56ba() {
6530         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6531                 skip "Need MDS version at least 2.10.50"
6532
6533         # Create composite files with one component
6534         local dir=$DIR/$tdir
6535
6536         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6537         # Create composite files with three components
6538         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6539         # Create non-composite files
6540         createmany -o $dir/${tfile}- 10
6541
6542         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6543
6544         [[ $nfiles == 10 ]] ||
6545                 error "lfs find -E 1M found $nfiles != 10 files"
6546
6547         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6548         [[ $nfiles == 25 ]] ||
6549                 error "lfs find ! -E 1M found $nfiles != 25 files"
6550
6551         # All files have a component that starts at 0
6552         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6553         [[ $nfiles == 35 ]] ||
6554                 error "lfs find --component-start 0 - $nfiles != 35 files"
6555
6556         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6557         [[ $nfiles == 15 ]] ||
6558                 error "lfs find --component-start 2M - $nfiles != 15 files"
6559
6560         # All files created here have a componenet that does not starts at 2M
6561         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6562         [[ $nfiles == 35 ]] ||
6563                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6564
6565         # Find files with a specified number of components
6566         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6567         [[ $nfiles == 15 ]] ||
6568                 error "lfs find --component-count 3 - $nfiles != 15 files"
6569
6570         # Remember non-composite files have a component count of zero
6571         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6572         [[ $nfiles == 10 ]] ||
6573                 error "lfs find --component-count 0 - $nfiles != 10 files"
6574
6575         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6576         [[ $nfiles == 20 ]] ||
6577                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6578
6579         # All files have a flag called "init"
6580         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6581         [[ $nfiles == 35 ]] ||
6582                 error "lfs find --component-flags init - $nfiles != 35 files"
6583
6584         # Multi-component files will have a component not initialized
6585         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6586         [[ $nfiles == 15 ]] ||
6587                 error "lfs find !--component-flags init - $nfiles != 15 files"
6588
6589         rm -rf $dir
6590
6591 }
6592 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6593
6594 test_56ca() {
6595         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6596                 skip "Need MDS version at least 2.10.57"
6597
6598         local td=$DIR/$tdir
6599         local tf=$td/$tfile
6600         local dir
6601         local nfiles
6602         local cmd
6603         local i
6604         local j
6605
6606         # create mirrored directories and mirrored files
6607         mkdir $td || error "mkdir $td failed"
6608         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6609         createmany -o $tf- 10 || error "create $tf- failed"
6610
6611         for i in $(seq 2); do
6612                 dir=$td/dir$i
6613                 mkdir $dir || error "mkdir $dir failed"
6614                 $LFS mirror create -N$((3 + i)) $dir ||
6615                         error "create mirrored dir $dir failed"
6616                 createmany -o $dir/$tfile- 10 ||
6617                         error "create $dir/$tfile- failed"
6618         done
6619
6620         # change the states of some mirrored files
6621         echo foo > $tf-6
6622         for i in $(seq 2); do
6623                 dir=$td/dir$i
6624                 for j in $(seq 4 9); do
6625                         echo foo > $dir/$tfile-$j
6626                 done
6627         done
6628
6629         # find mirrored files with specific mirror count
6630         cmd="$LFS find --mirror-count 3 --type f $td"
6631         nfiles=$($cmd | wc -l)
6632         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6633
6634         cmd="$LFS find ! --mirror-count 3 --type f $td"
6635         nfiles=$($cmd | wc -l)
6636         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6637
6638         cmd="$LFS find --mirror-count +2 --type f $td"
6639         nfiles=$($cmd | wc -l)
6640         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6641
6642         cmd="$LFS find --mirror-count -6 --type f $td"
6643         nfiles=$($cmd | wc -l)
6644         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6645
6646         # find mirrored files with specific file state
6647         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6648         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6649
6650         cmd="$LFS find --mirror-state=ro --type f $td"
6651         nfiles=$($cmd | wc -l)
6652         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6653
6654         cmd="$LFS find ! --mirror-state=ro --type f $td"
6655         nfiles=$($cmd | wc -l)
6656         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6657
6658         cmd="$LFS find --mirror-state=wp --type f $td"
6659         nfiles=$($cmd | wc -l)
6660         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6661
6662         cmd="$LFS find ! --mirror-state=sp --type f $td"
6663         nfiles=$($cmd | wc -l)
6664         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6665 }
6666 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6667
6668 test_57a() {
6669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6670         # note test will not do anything if MDS is not local
6671         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6672                 skip_env "ldiskfs only test"
6673         fi
6674         remote_mds_nodsh && skip "remote MDS with nodsh"
6675
6676         local MNTDEV="osd*.*MDT*.mntdev"
6677         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6678         [ -z "$DEV" ] && error "can't access $MNTDEV"
6679         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6680                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6681                         error "can't access $DEV"
6682                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6683                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6684                 rm $TMP/t57a.dump
6685         done
6686 }
6687 run_test 57a "verify MDS filesystem created with large inodes =="
6688
6689 test_57b() {
6690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6691         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6692                 skip_env "ldiskfs only test"
6693         fi
6694         remote_mds_nodsh && skip "remote MDS with nodsh"
6695
6696         local dir=$DIR/$tdir
6697         local filecount=100
6698         local file1=$dir/f1
6699         local fileN=$dir/f$filecount
6700
6701         rm -rf $dir || error "removing $dir"
6702         test_mkdir -c1 $dir
6703         local mdtidx=$($LFS getstripe -m $dir)
6704         local mdtname=MDT$(printf %04x $mdtidx)
6705         local facet=mds$((mdtidx + 1))
6706
6707         echo "mcreating $filecount files"
6708         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6709
6710         # verify that files do not have EAs yet
6711         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6712                 error "$file1 has an EA"
6713         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6714                 error "$fileN has an EA"
6715
6716         sync
6717         sleep 1
6718         df $dir  #make sure we get new statfs data
6719         local mdsfree=$(do_facet $facet \
6720                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6721         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6722         local file
6723
6724         echo "opening files to create objects/EAs"
6725         for file in $(seq -f $dir/f%g 1 $filecount); do
6726                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6727                         error "opening $file"
6728         done
6729
6730         # verify that files have EAs now
6731         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6732         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6733
6734         sleep 1  #make sure we get new statfs data
6735         df $dir
6736         local mdsfree2=$(do_facet $facet \
6737                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6738         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6739
6740         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6741                 if [ "$mdsfree" != "$mdsfree2" ]; then
6742                         error "MDC before $mdcfree != after $mdcfree2"
6743                 else
6744                         echo "MDC before $mdcfree != after $mdcfree2"
6745                         echo "unable to confirm if MDS has large inodes"
6746                 fi
6747         fi
6748         rm -rf $dir
6749 }
6750 run_test 57b "default LOV EAs are stored inside large inodes ==="
6751
6752 test_58() {
6753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6754         [ -z "$(which wiretest 2>/dev/null)" ] &&
6755                         skip_env "could not find wiretest"
6756
6757         wiretest
6758 }
6759 run_test 58 "verify cross-platform wire constants =============="
6760
6761 test_59() {
6762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6763
6764         echo "touch 130 files"
6765         createmany -o $DIR/f59- 130
6766         echo "rm 130 files"
6767         unlinkmany $DIR/f59- 130
6768         sync
6769         # wait for commitment of removal
6770         wait_delete_completed
6771 }
6772 run_test 59 "verify cancellation of llog records async ========="
6773
6774 TEST60_HEAD="test_60 run $RANDOM"
6775 test_60a() {
6776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6777         remote_mgs_nodsh && skip "remote MGS with nodsh"
6778         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6779                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6780                         skip_env "missing subtest run-llog.sh"
6781
6782         log "$TEST60_HEAD - from kernel mode"
6783         do_facet mgs "$LCTL dk > /dev/null"
6784         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6785         do_facet mgs $LCTL dk > $TMP/$tfile
6786
6787         # LU-6388: test llog_reader
6788         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6789         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6790         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6791                         skip_env "missing llog_reader"
6792         local fstype=$(facet_fstype mgs)
6793         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6794                 skip_env "Only for ldiskfs or zfs type mgs"
6795
6796         local mntpt=$(facet_mntpt mgs)
6797         local mgsdev=$(mgsdevname 1)
6798         local fid_list
6799         local fid
6800         local rec_list
6801         local rec
6802         local rec_type
6803         local obj_file
6804         local path
6805         local seq
6806         local oid
6807         local pass=true
6808
6809         #get fid and record list
6810         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6811                 tail -n 4))
6812         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6813                 tail -n 4))
6814         #remount mgs as ldiskfs or zfs type
6815         stop mgs || error "stop mgs failed"
6816         mount_fstype mgs || error "remount mgs failed"
6817         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6818                 fid=${fid_list[i]}
6819                 rec=${rec_list[i]}
6820                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6821                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6822                 oid=$((16#$oid))
6823
6824                 case $fstype in
6825                         ldiskfs )
6826                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6827                         zfs )
6828                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6829                 esac
6830                 echo "obj_file is $obj_file"
6831                 do_facet mgs $llog_reader $obj_file
6832
6833                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6834                         awk '{ print $3 }' | sed -e "s/^type=//g")
6835                 if [ $rec_type != $rec ]; then
6836                         echo "FAILED test_60a wrong record type $rec_type," \
6837                               "should be $rec"
6838                         pass=false
6839                         break
6840                 fi
6841
6842                 #check obj path if record type is LLOG_LOGID_MAGIC
6843                 if [ "$rec" == "1064553b" ]; then
6844                         path=$(do_facet mgs $llog_reader $obj_file |
6845                                 grep "path=" | awk '{ print $NF }' |
6846                                 sed -e "s/^path=//g")
6847                         if [ $obj_file != $mntpt/$path ]; then
6848                                 echo "FAILED test_60a wrong obj path" \
6849                                       "$montpt/$path, should be $obj_file"
6850                                 pass=false
6851                                 break
6852                         fi
6853                 fi
6854         done
6855         rm -f $TMP/$tfile
6856         #restart mgs before "error", otherwise it will block the next test
6857         stop mgs || error "stop mgs failed"
6858         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6859         $pass || error "test failed, see FAILED test_60a messages for specifics"
6860 }
6861 run_test 60a "llog_test run from kernel module and test llog_reader"
6862
6863 test_60b() { # bug 6411
6864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6865
6866         dmesg > $DIR/$tfile
6867         LLOG_COUNT=$(do_facet mgs dmesg |
6868                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6869                           /llog_[a-z]*.c:[0-9]/ {
6870                                 if (marker)
6871                                         from_marker++
6872                                 from_begin++
6873                           }
6874                           END {
6875                                 if (marker)
6876                                         print from_marker
6877                                 else
6878                                         print from_begin
6879                           }")
6880
6881         [[ $LLOG_COUNT -gt 120 ]] &&
6882                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6883 }
6884 run_test 60b "limit repeated messages from CERROR/CWARN"
6885
6886 test_60c() {
6887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6888
6889         echo "create 5000 files"
6890         createmany -o $DIR/f60c- 5000
6891 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6892         lctl set_param fail_loc=0x80000137
6893         unlinkmany $DIR/f60c- 5000
6894         lctl set_param fail_loc=0
6895 }
6896 run_test 60c "unlink file when mds full"
6897
6898 test_60d() {
6899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6900
6901         SAVEPRINTK=$(lctl get_param -n printk)
6902         # verify "lctl mark" is even working"
6903         MESSAGE="test message ID $RANDOM $$"
6904         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6905         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6906
6907         lctl set_param printk=0 || error "set lnet.printk failed"
6908         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6909         MESSAGE="new test message ID $RANDOM $$"
6910         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6911         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6912         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6913
6914         lctl set_param -n printk="$SAVEPRINTK"
6915 }
6916 run_test 60d "test printk console message masking"
6917
6918 test_60e() {
6919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6920         remote_mds_nodsh && skip "remote MDS with nodsh"
6921
6922         touch $DIR/$tfile
6923 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6924         do_facet mds1 lctl set_param fail_loc=0x15b
6925         rm $DIR/$tfile
6926 }
6927 run_test 60e "no space while new llog is being created"
6928
6929 test_60g() {
6930         local pid
6931
6932         test_mkdir -c $MDSCOUNT $DIR/$tdir
6933         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6934
6935         (
6936                 local index=0
6937                 while true; do
6938                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6939                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6940                         index=$((index + 1))
6941                 done
6942         ) &
6943
6944         pid=$!
6945
6946         for i in $(seq 100); do 
6947                 # define OBD_FAIL_OSD_TXN_START    0x19a
6948                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6949                 usleep 100
6950         done
6951
6952         kill -9 $pid
6953
6954         mkdir $DIR/$tdir/new || error "mkdir failed"
6955         rmdir $DIR/$tdir/new || error "rmdir failed"
6956 }
6957 run_test 60g "transaction abort won't cause MDT hung"
6958
6959 test_60h() {
6960         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6961                 skip "Need MDS version at least 2.12.52"
6962         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6963
6964         local f
6965
6966         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6967         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6968         for fail_loc in 0x80000188 0x80000189; do
6969                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6970                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6971                         error "mkdir $dir-$fail_loc failed"
6972                 for i in {0..10}; do
6973                         # create may fail on missing stripe
6974                         echo $i > $DIR/$tdir-$fail_loc/$i
6975                 done
6976                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6977                         error "getdirstripe $tdir-$fail_loc failed"
6978                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6979                         error "migrate $tdir-$fail_loc failed"
6980                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6981                         error "getdirstripe $tdir-$fail_loc failed"
6982                 pushd $DIR/$tdir-$fail_loc
6983                 for f in *; do
6984                         echo $f | cmp $f - || error "$f data mismatch"
6985                 done
6986                 popd
6987                 rm -rf $DIR/$tdir-$fail_loc
6988         done
6989 }
6990 run_test 60h "striped directory with missing stripes can be accessed"
6991
6992 test_61a() {
6993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6994
6995         f="$DIR/f61"
6996         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6997         cancel_lru_locks osc
6998         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6999         sync
7000 }
7001 run_test 61a "mmap() writes don't make sync hang ================"
7002
7003 test_61b() {
7004         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7005 }
7006 run_test 61b "mmap() of unstriped file is successful"
7007
7008 # bug 2330 - insufficient obd_match error checking causes LBUG
7009 test_62() {
7010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7011
7012         f="$DIR/f62"
7013         echo foo > $f
7014         cancel_lru_locks osc
7015         lctl set_param fail_loc=0x405
7016         cat $f && error "cat succeeded, expect -EIO"
7017         lctl set_param fail_loc=0
7018 }
7019 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7020 # match every page all of the time.
7021 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7022
7023 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7024 # Though this test is irrelevant anymore, it helped to reveal some
7025 # other grant bugs (LU-4482), let's keep it.
7026 test_63a() {   # was test_63
7027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7028
7029         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7030
7031         for i in `seq 10` ; do
7032                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7033                 sleep 5
7034                 kill $!
7035                 sleep 1
7036         done
7037
7038         rm -f $DIR/f63 || true
7039 }
7040 run_test 63a "Verify oig_wait interruption does not crash ======="
7041
7042 # bug 2248 - async write errors didn't return to application on sync
7043 # bug 3677 - async write errors left page locked
7044 test_63b() {
7045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7046
7047         debugsave
7048         lctl set_param debug=-1
7049
7050         # ensure we have a grant to do async writes
7051         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7052         rm $DIR/$tfile
7053
7054         sync    # sync lest earlier test intercept the fail_loc
7055
7056         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7057         lctl set_param fail_loc=0x80000406
7058         $MULTIOP $DIR/$tfile Owy && \
7059                 error "sync didn't return ENOMEM"
7060         sync; sleep 2; sync     # do a real sync this time to flush page
7061         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7062                 error "locked page left in cache after async error" || true
7063         debugrestore
7064 }
7065 run_test 63b "async write errors should be returned to fsync ==="
7066
7067 test_64a () {
7068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7069
7070         df $DIR
7071         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7072 }
7073 run_test 64a "verify filter grant calculations (in kernel) ====="
7074
7075 test_64b () {
7076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7077
7078         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7079 }
7080 run_test 64b "check out-of-space detection on client"
7081
7082 test_64c() {
7083         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7084 }
7085 run_test 64c "verify grant shrink"
7086
7087 # this does exactly what osc_request.c:osc_announce_cached() does in
7088 # order to calculate max amount of grants to ask from server
7089 want_grant() {
7090         local tgt=$1
7091
7092         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7093         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7094
7095         ((rpc_in_flight ++));
7096         nrpages=$((nrpages * rpc_in_flight))
7097
7098         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7099
7100         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7101
7102         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7103         local undirty=$((nrpages * PAGE_SIZE))
7104
7105         local max_extent_pages
7106         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7107             grep grant_max_extent_size | awk '{print $2}')
7108         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7109         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7110         local grant_extent_tax
7111         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7112             grep grant_extent_tax | awk '{print $2}')
7113
7114         undirty=$((undirty + nrextents * grant_extent_tax))
7115
7116         echo $undirty
7117 }
7118
7119 # this is size of unit for grant allocation. It should be equal to
7120 # what tgt_grant.c:tgt_grant_chunk() calculates
7121 grant_chunk() {
7122         local tgt=$1
7123         local max_brw_size
7124         local grant_extent_tax
7125
7126         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7127             grep max_brw_size | awk '{print $2}')
7128
7129         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7130             grep grant_extent_tax | awk '{print $2}')
7131
7132         echo $(((max_brw_size + grant_extent_tax) * 2))
7133 }
7134
7135 test_64d() {
7136         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7137                 skip "OST < 2.10.55 doesn't limit grants enough"
7138
7139         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7140         local file=$DIR/$tfile
7141
7142         [[ $($LCTL get_param osc.${tgt}.import |
7143              grep "connect_flags:.*grant_param") ]] ||
7144                 skip "no grant_param connect flag"
7145
7146         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7147
7148         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7149
7150         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7151         stack_trap "rm -f $file" EXIT
7152
7153         $LFS setstripe $file -i 0 -c 1
7154         dd if=/dev/zero of=$file bs=1M count=1000 &
7155         ddpid=$!
7156
7157         while true
7158         do
7159                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7160                 if [[ $cur_grant -gt $max_cur_granted ]]
7161                 then
7162                         kill $ddpid
7163                         error "cur_grant $cur_grant > $max_cur_granted"
7164                 fi
7165                 kill -0 $ddpid
7166                 [[ $? -ne 0 ]] && break;
7167                 sleep 2
7168         done
7169
7170         rm -f $DIR/$tfile
7171         wait_delete_completed
7172         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7173 }
7174 run_test 64d "check grant limit exceed"
7175
7176 # bug 1414 - set/get directories' stripe info
7177 test_65a() {
7178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7179
7180         test_mkdir $DIR/$tdir
7181         touch $DIR/$tdir/f1
7182         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7183 }
7184 run_test 65a "directory with no stripe info"
7185
7186 test_65b() {
7187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7188
7189         test_mkdir $DIR/$tdir
7190         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7191
7192         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7193                                                 error "setstripe"
7194         touch $DIR/$tdir/f2
7195         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7196 }
7197 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7198
7199 test_65c() {
7200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7201         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7202
7203         test_mkdir $DIR/$tdir
7204         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7205
7206         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7207                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7208         touch $DIR/$tdir/f3
7209         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7210 }
7211 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7212
7213 test_65d() {
7214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7215
7216         test_mkdir $DIR/$tdir
7217         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7218         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7219
7220         if [[ $STRIPECOUNT -le 0 ]]; then
7221                 sc=1
7222         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7223                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7224                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7225         else
7226                 sc=$(($STRIPECOUNT - 1))
7227         fi
7228         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7229         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7230         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7231                 error "lverify failed"
7232 }
7233 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7234
7235 test_65e() {
7236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7237
7238         test_mkdir $DIR/$tdir
7239
7240         $LFS setstripe $DIR/$tdir || error "setstripe"
7241         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7242                                         error "no stripe info failed"
7243         touch $DIR/$tdir/f6
7244         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7245 }
7246 run_test 65e "directory setstripe defaults"
7247
7248 test_65f() {
7249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7250
7251         test_mkdir $DIR/${tdir}f
7252         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7253                 error "setstripe succeeded" || true
7254 }
7255 run_test 65f "dir setstripe permission (should return error) ==="
7256
7257 test_65g() {
7258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7259
7260         test_mkdir $DIR/$tdir
7261         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7262
7263         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7264                 error "setstripe -S failed"
7265         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7266         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7267                 error "delete default stripe failed"
7268 }
7269 run_test 65g "directory setstripe -d"
7270
7271 test_65h() {
7272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7273
7274         test_mkdir $DIR/$tdir
7275         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7276
7277         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7278                 error "setstripe -S failed"
7279         test_mkdir $DIR/$tdir/dd1
7280         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7281                 error "stripe info inherit failed"
7282 }
7283 run_test 65h "directory stripe info inherit ===================="
7284
7285 test_65i() {
7286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7287
7288         save_layout_restore_at_exit $MOUNT
7289
7290         # bug6367: set non-default striping on root directory
7291         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7292
7293         # bug12836: getstripe on -1 default directory striping
7294         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7295
7296         # bug12836: getstripe -v on -1 default directory striping
7297         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7298
7299         # bug12836: new find on -1 default directory striping
7300         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7301 }
7302 run_test 65i "various tests to set root directory striping"
7303
7304 test_65j() { # bug6367
7305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7306
7307         sync; sleep 1
7308
7309         # if we aren't already remounting for each test, do so for this test
7310         if [ "$I_MOUNTED" = "yes" ]; then
7311                 cleanup || error "failed to unmount"
7312                 setup
7313         fi
7314
7315         save_layout_restore_at_exit $MOUNT
7316
7317         $LFS setstripe -d $MOUNT || error "setstripe failed"
7318 }
7319 run_test 65j "set default striping on root directory (bug 6367)="
7320
7321 cleanup_65k() {
7322         rm -rf $DIR/$tdir
7323         wait_delete_completed
7324         do_facet $SINGLEMDS "lctl set_param -n \
7325                 osp.$ost*MDT0000.max_create_count=$max_count"
7326         do_facet $SINGLEMDS "lctl set_param -n \
7327                 osp.$ost*MDT0000.create_count=$count"
7328         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7329         echo $INACTIVE_OSC "is Activate"
7330
7331         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7332 }
7333
7334 test_65k() { # bug11679
7335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7336         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7337         remote_mds_nodsh && skip "remote MDS with nodsh"
7338
7339         local disable_precreate=true
7340         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7341                 disable_precreate=false
7342
7343         echo "Check OST status: "
7344         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7345                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7346
7347         for OSC in $MDS_OSCS; do
7348                 echo $OSC "is active"
7349                 do_facet $SINGLEMDS lctl --device %$OSC activate
7350         done
7351
7352         for INACTIVE_OSC in $MDS_OSCS; do
7353                 local ost=$(osc_to_ost $INACTIVE_OSC)
7354                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7355                                lov.*md*.target_obd |
7356                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7357
7358                 mkdir -p $DIR/$tdir
7359                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7360                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7361
7362                 echo "Deactivate: " $INACTIVE_OSC
7363                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7364
7365                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7366                               osp.$ost*MDT0000.create_count")
7367                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7368                                   osp.$ost*MDT0000.max_create_count")
7369                 $disable_precreate &&
7370                         do_facet $SINGLEMDS "lctl set_param -n \
7371                                 osp.$ost*MDT0000.max_create_count=0"
7372
7373                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7374                         [ -f $DIR/$tdir/$idx ] && continue
7375                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7376                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7377                                 { cleanup_65k;
7378                                   error "setstripe $idx should succeed"; }
7379                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7380                 done
7381                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7382                 rmdir $DIR/$tdir
7383
7384                 do_facet $SINGLEMDS "lctl set_param -n \
7385                         osp.$ost*MDT0000.max_create_count=$max_count"
7386                 do_facet $SINGLEMDS "lctl set_param -n \
7387                         osp.$ost*MDT0000.create_count=$count"
7388                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7389                 echo $INACTIVE_OSC "is Activate"
7390
7391                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7392         done
7393 }
7394 run_test 65k "validate manual striping works properly with deactivated OSCs"
7395
7396 test_65l() { # bug 12836
7397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7398
7399         test_mkdir -p $DIR/$tdir/test_dir
7400         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7401         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7402 }
7403 run_test 65l "lfs find on -1 stripe dir ========================"
7404
7405 test_65m() {
7406         local layout=$(save_layout $MOUNT)
7407         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7408                 restore_layout $MOUNT $layout
7409                 error "setstripe should fail by non-root users"
7410         }
7411         true
7412 }
7413 run_test 65m "normal user can't set filesystem default stripe"
7414
7415 test_65n() {
7416         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7417         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7418                 skip "Need MDS version at least 2.12.50"
7419         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7420
7421         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7422         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7423         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7424
7425         local root_layout=$(save_layout $MOUNT)
7426         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7427
7428         # new subdirectory under root directory should not inherit
7429         # the default layout from root
7430         local dir1=$MOUNT/$tdir-1
7431         mkdir $dir1 || error "mkdir $dir1 failed"
7432         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7433                 error "$dir1 shouldn't have LOV EA"
7434
7435         # delete the default layout on root directory
7436         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7437
7438         local dir2=$MOUNT/$tdir-2
7439         mkdir $dir2 || error "mkdir $dir2 failed"
7440         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7441                 error "$dir2 shouldn't have LOV EA"
7442
7443         # set a new striping pattern on root directory
7444         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7445         local new_def_stripe_size=$((def_stripe_size * 2))
7446         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7447                 error "set stripe size on $MOUNT failed"
7448
7449         # new file created in $dir2 should inherit the new stripe size from
7450         # the filesystem default
7451         local file2=$dir2/$tfile-2
7452         touch $file2 || error "touch $file2 failed"
7453
7454         local file2_stripe_size=$($LFS getstripe -S $file2)
7455         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7456                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7457
7458         local dir3=$MOUNT/$tdir-3
7459         mkdir $dir3 || error "mkdir $dir3 failed"
7460         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7461                 error "$dir3 shouldn't have LOV EA"
7462
7463         # set OST pool on root directory
7464         local pool=$TESTNAME
7465         pool_add $pool || error "add $pool failed"
7466         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7467                 error "add targets to $pool failed"
7468
7469         $LFS setstripe -p $pool $MOUNT ||
7470                 error "set OST pool on $MOUNT failed"
7471
7472         # new file created in $dir3 should inherit the pool from
7473         # the filesystem default
7474         local file3=$dir3/$tfile-3
7475         touch $file3 || error "touch $file3 failed"
7476
7477         local file3_pool=$($LFS getstripe -p $file3)
7478         [[ "$file3_pool" = "$pool" ]] ||
7479                 error "$file3 didn't inherit OST pool $pool"
7480
7481         local dir4=$MOUNT/$tdir-4
7482         mkdir $dir4 || error "mkdir $dir4 failed"
7483         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7484                 error "$dir4 shouldn't have LOV EA"
7485
7486         # new file created in $dir4 should inherit the pool from
7487         # the filesystem default
7488         local file4=$dir4/$tfile-4
7489         touch $file4 || error "touch $file4 failed"
7490
7491         local file4_pool=$($LFS getstripe -p $file4)
7492         [[ "$file4_pool" = "$pool" ]] ||
7493                 error "$file4 didn't inherit OST pool $pool"
7494
7495         # new subdirectory under non-root directory should inherit
7496         # the default layout from its parent directory
7497         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7498                 error "set directory layout on $dir4 failed"
7499
7500         local dir5=$dir4/$tdir-5
7501         mkdir $dir5 || error "mkdir $dir5 failed"
7502
7503         local dir4_layout=$(get_layout_param $dir4)
7504         local dir5_layout=$(get_layout_param $dir5)
7505         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7506                 error "$dir5 should inherit the default layout from $dir4"
7507 }
7508 run_test 65n "don't inherit default layout from root for new subdirectories"
7509
7510 # bug 2543 - update blocks count on client
7511 test_66() {
7512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7513
7514         COUNT=${COUNT:-8}
7515         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7516         sync; sync_all_data; sync; sync_all_data
7517         cancel_lru_locks osc
7518         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7519         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7520 }
7521 run_test 66 "update inode blocks count on client ==============="
7522
7523 meminfo() {
7524         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7525 }
7526
7527 swap_used() {
7528         swapon -s | awk '($1 == "'$1'") { print $4 }'
7529 }
7530
7531 # bug5265, obdfilter oa2dentry return -ENOENT
7532 # #define OBD_FAIL_SRV_ENOENT 0x217
7533 test_69() {
7534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7535         remote_ost_nodsh && skip "remote OST with nodsh"
7536
7537         f="$DIR/$tfile"
7538         $LFS setstripe -c 1 -i 0 $f
7539
7540         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7541
7542         do_facet ost1 lctl set_param fail_loc=0x217
7543         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7544         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7545
7546         do_facet ost1 lctl set_param fail_loc=0
7547         $DIRECTIO write $f 0 2 || error "write error"
7548
7549         cancel_lru_locks osc
7550         $DIRECTIO read $f 0 1 || error "read error"
7551
7552         do_facet ost1 lctl set_param fail_loc=0x217
7553         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7554
7555         do_facet ost1 lctl set_param fail_loc=0
7556         rm -f $f
7557 }
7558 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7559
7560 test_71() {
7561         test_mkdir $DIR/$tdir
7562         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7563         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7564 }
7565 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7566
7567 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7569         [ "$RUNAS_ID" = "$UID" ] &&
7570                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7571         # Check that testing environment is properly set up. Skip if not
7572         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7573                 skip_env "User $RUNAS_ID does not exist - skipping"
7574
7575         touch $DIR/$tfile
7576         chmod 777 $DIR/$tfile
7577         chmod ug+s $DIR/$tfile
7578         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7579                 error "$RUNAS dd $DIR/$tfile failed"
7580         # See if we are still setuid/sgid
7581         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7582                 error "S/gid is not dropped on write"
7583         # Now test that MDS is updated too
7584         cancel_lru_locks mdc
7585         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7586                 error "S/gid is not dropped on MDS"
7587         rm -f $DIR/$tfile
7588 }
7589 run_test 72a "Test that remove suid works properly (bug5695) ===="
7590
7591 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7592         local perm
7593
7594         [ "$RUNAS_ID" = "$UID" ] &&
7595                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7596         [ "$RUNAS_ID" -eq 0 ] &&
7597                 skip_env "RUNAS_ID = 0 -- skipping"
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599         # Check that testing environment is properly set up. Skip if not
7600         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7601                 skip_env "User $RUNAS_ID does not exist - skipping"
7602
7603         touch $DIR/${tfile}-f{g,u}
7604         test_mkdir $DIR/${tfile}-dg
7605         test_mkdir $DIR/${tfile}-du
7606         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7607         chmod g+s $DIR/${tfile}-{f,d}g
7608         chmod u+s $DIR/${tfile}-{f,d}u
7609         for perm in 777 2777 4777; do
7610                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7611                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7612                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7613                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7614         done
7615         true
7616 }
7617 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7618
7619 # bug 3462 - multiple simultaneous MDC requests
7620 test_73() {
7621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7622
7623         test_mkdir $DIR/d73-1
7624         test_mkdir $DIR/d73-2
7625         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7626         pid1=$!
7627
7628         lctl set_param fail_loc=0x80000129
7629         $MULTIOP $DIR/d73-1/f73-2 Oc &
7630         sleep 1
7631         lctl set_param fail_loc=0
7632
7633         $MULTIOP $DIR/d73-2/f73-3 Oc &
7634         pid3=$!
7635
7636         kill -USR1 $pid1
7637         wait $pid1 || return 1
7638
7639         sleep 25
7640
7641         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7642         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7643         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7644
7645         rm -rf $DIR/d73-*
7646 }
7647 run_test 73 "multiple MDC requests (should not deadlock)"
7648
7649 test_74a() { # bug 6149, 6184
7650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7651
7652         touch $DIR/f74a
7653         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7654         #
7655         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7656         # will spin in a tight reconnection loop
7657         $LCTL set_param fail_loc=0x8000030e
7658         # get any lock that won't be difficult - lookup works.
7659         ls $DIR/f74a
7660         $LCTL set_param fail_loc=0
7661         rm -f $DIR/f74a
7662         true
7663 }
7664 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7665
7666 test_74b() { # bug 13310
7667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7668
7669         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7670         #
7671         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7672         # will spin in a tight reconnection loop
7673         $LCTL set_param fail_loc=0x8000030e
7674         # get a "difficult" lock
7675         touch $DIR/f74b
7676         $LCTL set_param fail_loc=0
7677         rm -f $DIR/f74b
7678         true
7679 }
7680 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7681
7682 test_74c() {
7683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7684
7685         #define OBD_FAIL_LDLM_NEW_LOCK
7686         $LCTL set_param fail_loc=0x319
7687         touch $DIR/$tfile && error "touch successful"
7688         $LCTL set_param fail_loc=0
7689         true
7690 }
7691 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7692
7693 num_inodes() {
7694         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7695 }
7696
7697 test_76() { # Now for bug 20433, added originally in bug 1443
7698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7699
7700         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7701
7702         cancel_lru_locks osc
7703         BEFORE_INODES=$(num_inodes)
7704         echo "before inodes: $BEFORE_INODES"
7705         local COUNT=1000
7706         [ "$SLOW" = "no" ] && COUNT=100
7707         for i in $(seq $COUNT); do
7708                 touch $DIR/$tfile
7709                 rm -f $DIR/$tfile
7710         done
7711         cancel_lru_locks osc
7712         AFTER_INODES=$(num_inodes)
7713         echo "after inodes: $AFTER_INODES"
7714         local wait=0
7715         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7716                 sleep 2
7717                 AFTER_INODES=$(num_inodes)
7718                 wait=$((wait+2))
7719                 echo "wait $wait seconds inodes: $AFTER_INODES"
7720                 if [ $wait -gt 30 ]; then
7721                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7722                 fi
7723         done
7724 }
7725 run_test 76 "confirm clients recycle inodes properly ===="
7726
7727
7728 export ORIG_CSUM=""
7729 set_checksums()
7730 {
7731         # Note: in sptlrpc modes which enable its own bulk checksum, the
7732         # original crc32_le bulk checksum will be automatically disabled,
7733         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7734         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7735         # In this case set_checksums() will not be no-op, because sptlrpc
7736         # bulk checksum will be enabled all through the test.
7737
7738         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7739         lctl set_param -n osc.*.checksums $1
7740         return 0
7741 }
7742
7743 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7744                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7745 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7746                              tr -d [] | head -n1)}
7747 set_checksum_type()
7748 {
7749         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7750         log "set checksum type to $1"
7751         return 0
7752 }
7753 F77_TMP=$TMP/f77-temp
7754 F77SZ=8
7755 setup_f77() {
7756         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7757                 error "error writing to $F77_TMP"
7758 }
7759
7760 test_77a() { # bug 10889
7761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7762         $GSS && skip_env "could not run with gss"
7763
7764         [ ! -f $F77_TMP ] && setup_f77
7765         set_checksums 1
7766         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7767         set_checksums 0
7768         rm -f $DIR/$tfile
7769 }
7770 run_test 77a "normal checksum read/write operation"
7771
7772 test_77b() { # bug 10889
7773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7774         $GSS && skip_env "could not run with gss"
7775
7776         [ ! -f $F77_TMP ] && setup_f77
7777         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7778         $LCTL set_param fail_loc=0x80000409
7779         set_checksums 1
7780
7781         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7782                 error "dd error: $?"
7783         $LCTL set_param fail_loc=0
7784
7785         for algo in $CKSUM_TYPES; do
7786                 cancel_lru_locks osc
7787                 set_checksum_type $algo
7788                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7789                 $LCTL set_param fail_loc=0x80000408
7790                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7791                 $LCTL set_param fail_loc=0
7792         done
7793         set_checksums 0
7794         set_checksum_type $ORIG_CSUM_TYPE
7795         rm -f $DIR/$tfile
7796 }
7797 run_test 77b "checksum error on client write, read"
7798
7799 cleanup_77c() {
7800         trap 0
7801         set_checksums 0
7802         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7803         $check_ost &&
7804                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7805         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7806         $check_ost && [ -n "$ost_file_prefix" ] &&
7807                 do_facet ost1 rm -f ${ost_file_prefix}\*
7808 }
7809
7810 test_77c() {
7811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7812         $GSS && skip_env "could not run with gss"
7813         remote_ost_nodsh && skip "remote OST with nodsh"
7814
7815         local bad1
7816         local osc_file_prefix
7817         local osc_file
7818         local check_ost=false
7819         local ost_file_prefix
7820         local ost_file
7821         local orig_cksum
7822         local dump_cksum
7823         local fid
7824
7825         # ensure corruption will occur on first OSS/OST
7826         $LFS setstripe -i 0 $DIR/$tfile
7827
7828         [ ! -f $F77_TMP ] && setup_f77
7829         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7830                 error "dd write error: $?"
7831         fid=$($LFS path2fid $DIR/$tfile)
7832
7833         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7834         then
7835                 check_ost=true
7836                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7837                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7838         else
7839                 echo "OSS do not support bulk pages dump upon error"
7840         fi
7841
7842         osc_file_prefix=$($LCTL get_param -n debug_path)
7843         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7844
7845         trap cleanup_77c EXIT
7846
7847         set_checksums 1
7848         # enable bulk pages dump upon error on Client
7849         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7850         # enable bulk pages dump upon error on OSS
7851         $check_ost &&
7852                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7853
7854         # flush Client cache to allow next read to reach OSS
7855         cancel_lru_locks osc
7856
7857         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7858         $LCTL set_param fail_loc=0x80000408
7859         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7860         $LCTL set_param fail_loc=0
7861
7862         rm -f $DIR/$tfile
7863
7864         # check cksum dump on Client
7865         osc_file=$(ls ${osc_file_prefix}*)
7866         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7867         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7868         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7869         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7870         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7871                      cksum)
7872         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7873         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7874                 error "dump content does not match on Client"
7875
7876         $check_ost || skip "No need to check cksum dump on OSS"
7877
7878         # check cksum dump on OSS
7879         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7880         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7881         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7882         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7883         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7884                 error "dump content does not match on OSS"
7885
7886         cleanup_77c
7887 }
7888 run_test 77c "checksum error on client read with debug"
7889
7890 test_77d() { # bug 10889
7891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7892         $GSS && skip_env "could not run with gss"
7893
7894         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7895         $LCTL set_param fail_loc=0x80000409
7896         set_checksums 1
7897         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7898                 error "direct write: rc=$?"
7899         $LCTL set_param fail_loc=0
7900         set_checksums 0
7901
7902         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7903         $LCTL set_param fail_loc=0x80000408
7904         set_checksums 1
7905         cancel_lru_locks osc
7906         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7907                 error "direct read: rc=$?"
7908         $LCTL set_param fail_loc=0
7909         set_checksums 0
7910 }
7911 run_test 77d "checksum error on OST direct write, read"
7912
7913 test_77f() { # bug 10889
7914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7915         $GSS && skip_env "could not run with gss"
7916
7917         set_checksums 1
7918         for algo in $CKSUM_TYPES; do
7919                 cancel_lru_locks osc
7920                 set_checksum_type $algo
7921                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7922                 $LCTL set_param fail_loc=0x409
7923                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7924                         error "direct write succeeded"
7925                 $LCTL set_param fail_loc=0
7926         done
7927         set_checksum_type $ORIG_CSUM_TYPE
7928         set_checksums 0
7929 }
7930 run_test 77f "repeat checksum error on write (expect error)"
7931
7932 test_77g() { # bug 10889
7933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7934         $GSS && skip_env "could not run with gss"
7935         remote_ost_nodsh && skip "remote OST with nodsh"
7936
7937         [ ! -f $F77_TMP ] && setup_f77
7938
7939         local file=$DIR/$tfile
7940         stack_trap "rm -f $file" EXIT
7941
7942         $LFS setstripe -c 1 -i 0 $file
7943         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7944         do_facet ost1 lctl set_param fail_loc=0x8000021a
7945         set_checksums 1
7946         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7947                 error "write error: rc=$?"
7948         do_facet ost1 lctl set_param fail_loc=0
7949         set_checksums 0
7950
7951         cancel_lru_locks osc
7952         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7953         do_facet ost1 lctl set_param fail_loc=0x8000021b
7954         set_checksums 1
7955         cmp $F77_TMP $file || error "file compare failed"
7956         do_facet ost1 lctl set_param fail_loc=0
7957         set_checksums 0
7958 }
7959 run_test 77g "checksum error on OST write, read"
7960
7961 test_77k() { # LU-10906
7962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7963         $GSS && skip_env "could not run with gss"
7964
7965         local cksum_param="osc.$FSNAME*.checksums"
7966         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7967         local checksum
7968         local i
7969
7970         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7971         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7972         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7973                 EXIT
7974
7975         for i in 0 1; do
7976                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7977                         error "failed to set checksum=$i on MGS"
7978                 wait_update $HOSTNAME "$get_checksum" $i
7979                 #remount
7980                 echo "remount client, checksum should be $i"
7981                 remount_client $MOUNT || "failed to remount client"
7982                 checksum=$(eval $get_checksum)
7983                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7984         done
7985         # remove persistent param to avoid races with checksum mountopt below
7986         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7987                 error "failed to delete checksum on MGS"
7988
7989         for opt in "checksum" "nochecksum"; do
7990                 #remount with mount option
7991                 echo "remount client with option $opt, checksum should be $i"
7992                 umount_client $MOUNT || "failed to umount client"
7993                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7994                         "failed to mount client with option '$opt'"
7995                 checksum=$(eval $get_checksum)
7996                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7997                 i=$((i - 1))
7998         done
7999
8000         remount_client $MOUNT || "failed to remount client"
8001 }
8002 run_test 77k "enable/disable checksum correctly"
8003
8004 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8005 rm -f $F77_TMP
8006 unset F77_TMP
8007
8008 cleanup_test_78() {
8009         trap 0
8010         rm -f $DIR/$tfile
8011 }
8012
8013 test_78() { # bug 10901
8014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8015         remote_ost || skip_env "local OST"
8016
8017         NSEQ=5
8018         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8019         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8020         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8021         echo "MemTotal: $MEMTOTAL"
8022
8023         # reserve 256MB of memory for the kernel and other running processes,
8024         # and then take 1/2 of the remaining memory for the read/write buffers.
8025         if [ $MEMTOTAL -gt 512 ] ;then
8026                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8027         else
8028                 # for those poor memory-starved high-end clusters...
8029                 MEMTOTAL=$((MEMTOTAL / 2))
8030         fi
8031         echo "Mem to use for directio: $MEMTOTAL"
8032
8033         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8034         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8035         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8036         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8037                 head -n1)
8038         echo "Smallest OST: $SMALLESTOST"
8039         [[ $SMALLESTOST -lt 10240 ]] &&
8040                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8041
8042         trap cleanup_test_78 EXIT
8043
8044         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8045                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8046
8047         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8048         echo "File size: $F78SIZE"
8049         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8050         for i in $(seq 1 $NSEQ); do
8051                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8052                 echo directIO rdwr round $i of $NSEQ
8053                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8054         done
8055
8056         cleanup_test_78
8057 }
8058 run_test 78 "handle large O_DIRECT writes correctly ============"
8059
8060 test_79() { # bug 12743
8061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8062
8063         wait_delete_completed
8064
8065         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8066         BKFREE=$(calc_osc_kbytes kbytesfree)
8067         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8068
8069         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8070         DFTOTAL=`echo $STRING | cut -d, -f1`
8071         DFUSED=`echo $STRING  | cut -d, -f2`
8072         DFAVAIL=`echo $STRING | cut -d, -f3`
8073         DFFREE=$(($DFTOTAL - $DFUSED))
8074
8075         ALLOWANCE=$((64 * $OSTCOUNT))
8076
8077         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8078            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8079                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8080         fi
8081         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8082            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8083                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8084         fi
8085         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8086            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8087                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8088         fi
8089 }
8090 run_test 79 "df report consistency check ======================="
8091
8092 test_80() { # bug 10718
8093         remote_ost_nodsh && skip "remote OST with nodsh"
8094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8095
8096         # relax strong synchronous semantics for slow backends like ZFS
8097         local soc="obdfilter.*.sync_on_lock_cancel"
8098         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8099         local hosts=
8100         if [ "$soc_old" != "never" ] &&
8101                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8102                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8103                                 facet_active_host $host; done | sort -u)
8104                         do_nodes $hosts lctl set_param $soc=never
8105         fi
8106
8107         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8108         sync; sleep 1; sync
8109         local BEFORE=`date +%s`
8110         cancel_lru_locks osc
8111         local AFTER=`date +%s`
8112         local DIFF=$((AFTER-BEFORE))
8113         if [ $DIFF -gt 1 ] ; then
8114                 error "elapsed for 1M@1T = $DIFF"
8115         fi
8116
8117         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8118
8119         rm -f $DIR/$tfile
8120 }
8121 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8122
8123 test_81a() { # LU-456
8124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8125         remote_ost_nodsh && skip "remote OST with nodsh"
8126
8127         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8128         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8129         do_facet ost1 lctl set_param fail_loc=0x80000228
8130
8131         # write should trigger a retry and success
8132         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8133         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8134         RC=$?
8135         if [ $RC -ne 0 ] ; then
8136                 error "write should success, but failed for $RC"
8137         fi
8138 }
8139 run_test 81a "OST should retry write when get -ENOSPC ==============="
8140
8141 test_81b() { # LU-456
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143         remote_ost_nodsh && skip "remote OST with nodsh"
8144
8145         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8146         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8147         do_facet ost1 lctl set_param fail_loc=0x228
8148
8149         # write should retry several times and return -ENOSPC finally
8150         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8151         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8152         RC=$?
8153         ENOSPC=28
8154         if [ $RC -ne $ENOSPC ] ; then
8155                 error "dd should fail for -ENOSPC, but succeed."
8156         fi
8157 }
8158 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8159
8160 test_82() { # LU-1031
8161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8162         local gid1=14091995
8163         local gid2=16022000
8164
8165         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8166         local MULTIPID1=$!
8167         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8168         local MULTIPID2=$!
8169         kill -USR1 $MULTIPID2
8170         sleep 2
8171         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8172                 error "First grouplock does not block second one"
8173         else
8174                 echo "Second grouplock blocks first one"
8175         fi
8176         kill -USR1 $MULTIPID1
8177         wait $MULTIPID1
8178         wait $MULTIPID2
8179 }
8180 run_test 82 "Basic grouplock test"
8181
8182 test_99() {
8183         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8184
8185         test_mkdir $DIR/$tdir.cvsroot
8186         chown $RUNAS_ID $DIR/$tdir.cvsroot
8187
8188         cd $TMP
8189         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8190
8191         cd /etc/init.d
8192         # some versions of cvs import exit(1) when asked to import links or
8193         # files they can't read.  ignore those files.
8194         local toignore=$(find . -type l -printf '-I %f\n' -o \
8195                          ! -perm /4 -printf '-I %f\n')
8196         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8197                 $tdir.reposname vtag rtag
8198
8199         cd $DIR
8200         test_mkdir $DIR/$tdir.reposname
8201         chown $RUNAS_ID $DIR/$tdir.reposname
8202         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8203
8204         cd $DIR/$tdir.reposname
8205         $RUNAS touch foo99
8206         $RUNAS cvs add -m 'addmsg' foo99
8207         $RUNAS cvs update
8208         $RUNAS cvs commit -m 'nomsg' foo99
8209         rm -fr $DIR/$tdir.cvsroot
8210 }
8211 run_test 99 "cvs strange file/directory operations"
8212
8213 test_100() {
8214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8215         [[ "$NETTYPE" =~ tcp ]] ||
8216                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8217         remote_ost_nodsh && skip "remote OST with nodsh"
8218         remote_mds_nodsh && skip "remote MDS with nodsh"
8219         remote_servers ||
8220                 skip "useless for local single node setup"
8221
8222         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8223                 [ "$PROT" != "tcp" ] && continue
8224                 RPORT=$(echo $REMOTE | cut -d: -f2)
8225                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8226
8227                 rc=0
8228                 LPORT=`echo $LOCAL | cut -d: -f2`
8229                 if [ $LPORT -ge 1024 ]; then
8230                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8231                         netstat -tna
8232                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8233                 fi
8234         done
8235         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8236 }
8237 run_test 100 "check local port using privileged port ==========="
8238
8239 function get_named_value()
8240 {
8241     local tag
8242
8243     tag=$1
8244     while read ;do
8245         line=$REPLY
8246         case $line in
8247         $tag*)
8248             echo $line | sed "s/^$tag[ ]*//"
8249             break
8250             ;;
8251         esac
8252     done
8253 }
8254
8255 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8256                    awk '/^max_cached_mb/ { print $2 }')
8257
8258 cleanup_101a() {
8259         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8260         trap 0
8261 }
8262
8263 test_101a() {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8266
8267         local s
8268         local discard
8269         local nreads=10000
8270         local cache_limit=32
8271
8272         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8273         trap cleanup_101a EXIT
8274         $LCTL set_param -n llite.*.read_ahead_stats 0
8275         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8276
8277         #
8278         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8279         #
8280         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8281         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8282
8283         discard=0
8284         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8285                 get_named_value 'read but discarded' | cut -d" " -f1); do
8286                         discard=$(($discard + $s))
8287         done
8288         cleanup_101a
8289
8290         if [[ $(($discard * 10)) -gt $nreads ]]; then
8291                 $LCTL get_param osc.*-osc*.rpc_stats
8292                 $LCTL get_param llite.*.read_ahead_stats
8293                 error "too many ($discard) discarded pages"
8294         fi
8295         rm -f $DIR/$tfile || true
8296 }
8297 run_test 101a "check read-ahead for random reads"
8298
8299 setup_test101bc() {
8300         test_mkdir $DIR/$tdir
8301         local ssize=$1
8302         local FILE_LENGTH=$2
8303         STRIPE_OFFSET=0
8304
8305         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8306
8307         local list=$(comma_list $(osts_nodes))
8308         set_osd_param $list '' read_cache_enable 0
8309         set_osd_param $list '' writethrough_cache_enable 0
8310
8311         trap cleanup_test101bc EXIT
8312         # prepare the read-ahead file
8313         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8314
8315         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8316                                 count=$FILE_SIZE_MB 2> /dev/null
8317
8318 }
8319
8320 cleanup_test101bc() {
8321         trap 0
8322         rm -rf $DIR/$tdir
8323         rm -f $DIR/$tfile
8324
8325         local list=$(comma_list $(osts_nodes))
8326         set_osd_param $list '' read_cache_enable 1
8327         set_osd_param $list '' writethrough_cache_enable 1
8328 }
8329
8330 calc_total() {
8331         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8332 }
8333
8334 ra_check_101() {
8335         local READ_SIZE=$1
8336         local STRIPE_SIZE=$2
8337         local FILE_LENGTH=$3
8338         local RA_INC=1048576
8339         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8340         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8341                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8342         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8343                         get_named_value 'read but discarded' |
8344                         cut -d" " -f1 | calc_total)
8345         if [[ $DISCARD -gt $discard_limit ]]; then
8346                 $LCTL get_param llite.*.read_ahead_stats
8347                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8348         else
8349                 echo "Read-ahead success for size ${READ_SIZE}"
8350         fi
8351 }
8352
8353 test_101b() {
8354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8356
8357         local STRIPE_SIZE=1048576
8358         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8359
8360         if [ $SLOW == "yes" ]; then
8361                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8362         else
8363                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8364         fi
8365
8366         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8367
8368         # prepare the read-ahead file
8369         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8370         cancel_lru_locks osc
8371         for BIDX in 2 4 8 16 32 64 128 256
8372         do
8373                 local BSIZE=$((BIDX*4096))
8374                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8375                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8376                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8377                 $LCTL set_param -n llite.*.read_ahead_stats 0
8378                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8379                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8380                 cancel_lru_locks osc
8381                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8382         done
8383         cleanup_test101bc
8384         true
8385 }
8386 run_test 101b "check stride-io mode read-ahead ================="
8387
8388 test_101c() {
8389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8390
8391         local STRIPE_SIZE=1048576
8392         local FILE_LENGTH=$((STRIPE_SIZE*100))
8393         local nreads=10000
8394         local rsize=65536
8395         local osc_rpc_stats
8396
8397         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8398
8399         cancel_lru_locks osc
8400         $LCTL set_param osc.*.rpc_stats 0
8401         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8402         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8403                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8404                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8405                 local size
8406
8407                 if [ $lines -le 20 ]; then
8408                         continue
8409                 fi
8410                 for size in 1 2 4 8; do
8411                         local rpc=$(echo "$stats" |
8412                                     awk '($1 == "'$size':") {print $2; exit; }')
8413                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8414                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8415                 done
8416                 echo "$osc_rpc_stats check passed!"
8417         done
8418         cleanup_test101bc
8419         true
8420 }
8421 run_test 101c "check stripe_size aligned read-ahead ================="
8422
8423 set_read_ahead() {
8424         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8425         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8426 }
8427
8428 test_101d() {
8429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8430
8431         local file=$DIR/$tfile
8432         local sz_MB=${FILESIZE_101d:-500}
8433         local ra_MB=${READAHEAD_MB:-40}
8434
8435         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8436         [ $free_MB -lt $sz_MB ] &&
8437                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8438
8439         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8440         $LFS setstripe -c -1 $file || error "setstripe failed"
8441
8442         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8443         echo Cancel LRU locks on lustre client to flush the client cache
8444         cancel_lru_locks osc
8445
8446         echo Disable read-ahead
8447         local old_READAHEAD=$(set_read_ahead 0)
8448
8449         echo Reading the test file $file with read-ahead disabled
8450         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8451
8452         echo Cancel LRU locks on lustre client to flush the client cache
8453         cancel_lru_locks osc
8454         echo Enable read-ahead with ${ra_MB}MB
8455         set_read_ahead $ra_MB
8456
8457         echo Reading the test file $file with read-ahead enabled
8458         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8459
8460         echo "read-ahead disabled time read $raOFF"
8461         echo "read-ahead enabled  time read $raON"
8462
8463         set_read_ahead $old_READAHEAD
8464         rm -f $file
8465         wait_delete_completed
8466
8467         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8468                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8469 }
8470 run_test 101d "file read with and without read-ahead enabled"
8471
8472 test_101e() {
8473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8474
8475         local file=$DIR/$tfile
8476         local size_KB=500  #KB
8477         local count=100
8478         local bsize=1024
8479
8480         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8481         local need_KB=$((count * size_KB))
8482         [[ $free_KB -le $need_KB ]] &&
8483                 skip_env "Need free space $need_KB, have $free_KB"
8484
8485         echo "Creating $count ${size_KB}K test files"
8486         for ((i = 0; i < $count; i++)); do
8487                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8488         done
8489
8490         echo "Cancel LRU locks on lustre client to flush the client cache"
8491         cancel_lru_locks $OSC
8492
8493         echo "Reset readahead stats"
8494         $LCTL set_param -n llite.*.read_ahead_stats 0
8495
8496         for ((i = 0; i < $count; i++)); do
8497                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8498         done
8499
8500         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8501                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8502
8503         for ((i = 0; i < $count; i++)); do
8504                 rm -rf $file.$i 2>/dev/null
8505         done
8506
8507         #10000 means 20% reads are missing in readahead
8508         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8509 }
8510 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8511
8512 test_101f() {
8513         which iozone || skip_env "no iozone installed"
8514
8515         local old_debug=$($LCTL get_param debug)
8516         old_debug=${old_debug#*=}
8517         $LCTL set_param debug="reada mmap"
8518
8519         # create a test file
8520         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8521
8522         echo Cancel LRU locks on lustre client to flush the client cache
8523         cancel_lru_locks osc
8524
8525         echo Reset readahead stats
8526         $LCTL set_param -n llite.*.read_ahead_stats 0
8527
8528         echo mmap read the file with small block size
8529         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8530                 > /dev/null 2>&1
8531
8532         echo checking missing pages
8533         $LCTL get_param llite.*.read_ahead_stats
8534         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8535                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8536
8537         $LCTL set_param debug="$old_debug"
8538         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8539         rm -f $DIR/$tfile
8540 }
8541 run_test 101f "check mmap read performance"
8542
8543 test_101g_brw_size_test() {
8544         local mb=$1
8545         local pages=$((mb * 1048576 / PAGE_SIZE))
8546         local file=$DIR/$tfile
8547
8548         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8549                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8550         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8551                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8552                         return 2
8553         done
8554
8555         stack_trap "rm -f $file" EXIT
8556         $LCTL set_param -n osc.*.rpc_stats=0
8557
8558         # 10 RPCs should be enough for the test
8559         local count=10
8560         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8561                 { error "dd write ${mb} MB blocks failed"; return 3; }
8562         cancel_lru_locks osc
8563         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8564                 { error "dd write ${mb} MB blocks failed"; return 4; }
8565
8566         # calculate number of full-sized read and write RPCs
8567         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8568                 sed -n '/pages per rpc/,/^$/p' |
8569                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8570                 END { print reads,writes }'))
8571         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8572                 return 5
8573         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8574                 return 6
8575
8576         return 0
8577 }
8578
8579 test_101g() {
8580         remote_ost_nodsh && skip "remote OST with nodsh"
8581
8582         local rpcs
8583         local osts=$(get_facets OST)
8584         local list=$(comma_list $(osts_nodes))
8585         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8586         local brw_size="obdfilter.*.brw_size"
8587
8588         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8589
8590         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8591
8592         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8593                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8594                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8595            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8596                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8597                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8598
8599                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8600                         suffix="M"
8601
8602                 if [[ $orig_mb -lt 16 ]]; then
8603                         save_lustre_params $osts "$brw_size" > $p
8604                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8605                                 error "set 16MB RPC size failed"
8606
8607                         echo "remount client to enable new RPC size"
8608                         remount_client $MOUNT || error "remount_client failed"
8609                 fi
8610
8611                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8612                 # should be able to set brw_size=12, but no rpc_stats for that
8613                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8614         fi
8615
8616         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8617
8618         if [[ $orig_mb -lt 16 ]]; then
8619                 restore_lustre_params < $p
8620                 remount_client $MOUNT || error "remount_client restore failed"
8621         fi
8622
8623         rm -f $p $DIR/$tfile
8624 }
8625 run_test 101g "Big bulk(4/16 MiB) readahead"
8626
8627 test_101h() {
8628         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8629
8630         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
8631                 error "dd 70M file failed"
8632         echo Cancel LRU locks on lustre client to flush the client cache
8633         cancel_lru_locks osc
8634
8635         echo "Reset readahead stats"
8636         $LCTL set_param -n llite.*.read_ahead_stats 0
8637
8638         echo "Read 10M of data but cross 64M bundary"
8639         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
8640         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8641                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8642         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
8643         rm -f $p $DIR/$tfile
8644 }
8645 run_test 101h "Readahead should cover current read window"
8646
8647 setup_test102() {
8648         test_mkdir $DIR/$tdir
8649         chown $RUNAS_ID $DIR/$tdir
8650         STRIPE_SIZE=65536
8651         STRIPE_OFFSET=1
8652         STRIPE_COUNT=$OSTCOUNT
8653         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8654
8655         trap cleanup_test102 EXIT
8656         cd $DIR
8657         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8658         cd $DIR/$tdir
8659         for num in 1 2 3 4; do
8660                 for count in $(seq 1 $STRIPE_COUNT); do
8661                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8662                                 local size=`expr $STRIPE_SIZE \* $num`
8663                                 local file=file"$num-$idx-$count"
8664                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8665                         done
8666                 done
8667         done
8668
8669         cd $DIR
8670         $1 tar cf $TMP/f102.tar $tdir --xattrs
8671 }
8672
8673 cleanup_test102() {
8674         trap 0
8675         rm -f $TMP/f102.tar
8676         rm -rf $DIR/d0.sanity/d102
8677 }
8678
8679 test_102a() {
8680         [ "$UID" != 0 ] && skip "must run as root"
8681         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8682                 skip_env "must have user_xattr"
8683
8684         [ -z "$(which setfattr 2>/dev/null)" ] &&
8685                 skip_env "could not find setfattr"
8686
8687         local testfile=$DIR/$tfile
8688
8689         touch $testfile
8690         echo "set/get xattr..."
8691         setfattr -n trusted.name1 -v value1 $testfile ||
8692                 error "setfattr -n trusted.name1=value1 $testfile failed"
8693         getfattr -n trusted.name1 $testfile 2> /dev/null |
8694           grep "trusted.name1=.value1" ||
8695                 error "$testfile missing trusted.name1=value1"
8696
8697         setfattr -n user.author1 -v author1 $testfile ||
8698                 error "setfattr -n user.author1=author1 $testfile failed"
8699         getfattr -n user.author1 $testfile 2> /dev/null |
8700           grep "user.author1=.author1" ||
8701                 error "$testfile missing trusted.author1=author1"
8702
8703         echo "listxattr..."
8704         setfattr -n trusted.name2 -v value2 $testfile ||
8705                 error "$testfile unable to set trusted.name2"
8706         setfattr -n trusted.name3 -v value3 $testfile ||
8707                 error "$testfile unable to set trusted.name3"
8708         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8709             grep "trusted.name" | wc -l) -eq 3 ] ||
8710                 error "$testfile missing 3 trusted.name xattrs"
8711
8712         setfattr -n user.author2 -v author2 $testfile ||
8713                 error "$testfile unable to set user.author2"
8714         setfattr -n user.author3 -v author3 $testfile ||
8715                 error "$testfile unable to set user.author3"
8716         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8717             grep "user.author" | wc -l) -eq 3 ] ||
8718                 error "$testfile missing 3 user.author xattrs"
8719
8720         echo "remove xattr..."
8721         setfattr -x trusted.name1 $testfile ||
8722                 error "$testfile error deleting trusted.name1"
8723         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8724                 error "$testfile did not delete trusted.name1 xattr"
8725
8726         setfattr -x user.author1 $testfile ||
8727                 error "$testfile error deleting user.author1"
8728         echo "set lustre special xattr ..."
8729         $LFS setstripe -c1 $testfile
8730         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8731                 awk -F "=" '/trusted.lov/ { print $2 }' )
8732         setfattr -n "trusted.lov" -v $lovea $testfile ||
8733                 error "$testfile doesn't ignore setting trusted.lov again"
8734         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8735                 error "$testfile allow setting invalid trusted.lov"
8736         rm -f $testfile
8737 }
8738 run_test 102a "user xattr test =================================="
8739
8740 test_102b() {
8741         [ -z "$(which setfattr 2>/dev/null)" ] &&
8742                 skip_env "could not find setfattr"
8743         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8744
8745         # b10930: get/set/list trusted.lov xattr
8746         echo "get/set/list trusted.lov xattr ..."
8747         local testfile=$DIR/$tfile
8748         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8749                 error "setstripe failed"
8750         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8751                 error "getstripe failed"
8752         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8753                 error "can't get trusted.lov from $testfile"
8754
8755         local testfile2=${testfile}2
8756         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8757                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8758
8759         $MCREATE $testfile2
8760         setfattr -n trusted.lov -v $value $testfile2
8761         local stripe_size=$($LFS getstripe -S $testfile2)
8762         local stripe_count=$($LFS getstripe -c $testfile2)
8763         [[ $stripe_size -eq 65536 ]] ||
8764                 error "stripe size $stripe_size != 65536"
8765         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8766                 error "stripe count $stripe_count != $STRIPECOUNT"
8767         rm -f $DIR/$tfile
8768 }
8769 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8770
8771 test_102c() {
8772         [ -z "$(which setfattr 2>/dev/null)" ] &&
8773                 skip_env "could not find setfattr"
8774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8775
8776         # b10930: get/set/list lustre.lov xattr
8777         echo "get/set/list lustre.lov xattr ..."
8778         test_mkdir $DIR/$tdir
8779         chown $RUNAS_ID $DIR/$tdir
8780         local testfile=$DIR/$tdir/$tfile
8781         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8782                 error "setstripe failed"
8783         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8784                 error "getstripe failed"
8785         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8786         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8787
8788         local testfile2=${testfile}2
8789         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8790                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8791
8792         $RUNAS $MCREATE $testfile2
8793         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8794         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8795         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8796         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8797         [ $stripe_count -eq $STRIPECOUNT ] ||
8798                 error "stripe count $stripe_count != $STRIPECOUNT"
8799 }
8800 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8801
8802 compare_stripe_info1() {
8803         local stripe_index_all_zero=true
8804
8805         for num in 1 2 3 4; do
8806                 for count in $(seq 1 $STRIPE_COUNT); do
8807                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8808                                 local size=$((STRIPE_SIZE * num))
8809                                 local file=file"$num-$offset-$count"
8810                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8811                                 [[ $stripe_size -ne $size ]] &&
8812                                     error "$file: size $stripe_size != $size"
8813                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8814                                 # allow fewer stripes to be created, ORI-601
8815                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8816                                     error "$file: count $stripe_count != $count"
8817                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8818                                 [[ $stripe_index -ne 0 ]] &&
8819                                         stripe_index_all_zero=false
8820                         done
8821                 done
8822         done
8823         $stripe_index_all_zero &&
8824                 error "all files are being extracted starting from OST index 0"
8825         return 0
8826 }
8827
8828 have_xattrs_include() {
8829         tar --help | grep -q xattrs-include &&
8830                 echo --xattrs-include="lustre.*"
8831 }
8832
8833 test_102d() {
8834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8836
8837         XINC=$(have_xattrs_include)
8838         setup_test102
8839         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8840         cd $DIR/$tdir/$tdir
8841         compare_stripe_info1
8842 }
8843 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8844
8845 test_102f() {
8846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8848
8849         XINC=$(have_xattrs_include)
8850         setup_test102
8851         test_mkdir $DIR/$tdir.restore
8852         cd $DIR
8853         tar cf - --xattrs $tdir | tar xf - \
8854                 -C $DIR/$tdir.restore --xattrs $XINC
8855         cd $DIR/$tdir.restore/$tdir
8856         compare_stripe_info1
8857 }
8858 run_test 102f "tar copy files, not keep osts"
8859
8860 grow_xattr() {
8861         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8862                 skip "must have user_xattr"
8863         [ -z "$(which setfattr 2>/dev/null)" ] &&
8864                 skip_env "could not find setfattr"
8865         [ -z "$(which getfattr 2>/dev/null)" ] &&
8866                 skip_env "could not find getfattr"
8867
8868         local xsize=${1:-1024}  # in bytes
8869         local file=$DIR/$tfile
8870         local value="$(generate_string $xsize)"
8871         local xbig=trusted.big
8872         local toobig=$2
8873
8874         touch $file
8875         log "save $xbig on $file"
8876         if [ -z "$toobig" ]
8877         then
8878                 setfattr -n $xbig -v $value $file ||
8879                         error "saving $xbig on $file failed"
8880         else
8881                 setfattr -n $xbig -v $value $file &&
8882                         error "saving $xbig on $file succeeded"
8883                 return 0
8884         fi
8885
8886         local orig=$(get_xattr_value $xbig $file)
8887         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8888
8889         local xsml=trusted.sml
8890         log "save $xsml on $file"
8891         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8892
8893         local new=$(get_xattr_value $xbig $file)
8894         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8895
8896         log "grow $xsml on $file"
8897         setfattr -n $xsml -v "$value" $file ||
8898                 error "growing $xsml on $file failed"
8899
8900         new=$(get_xattr_value $xbig $file)
8901         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8902         log "$xbig still valid after growing $xsml"
8903
8904         rm -f $file
8905 }
8906
8907 test_102h() { # bug 15777
8908         grow_xattr 1024
8909 }
8910 run_test 102h "grow xattr from inside inode to external block"
8911
8912 test_102ha() {
8913         large_xattr_enabled || skip_env "ea_inode feature disabled"
8914
8915         echo "setting xattr of max xattr size: $(max_xattr_size)"
8916         grow_xattr $(max_xattr_size)
8917
8918         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8919         echo "This should fail:"
8920         grow_xattr $(($(max_xattr_size) + 10)) 1
8921 }
8922 run_test 102ha "grow xattr from inside inode to external inode"
8923
8924 test_102i() { # bug 17038
8925         [ -z "$(which getfattr 2>/dev/null)" ] &&
8926                 skip "could not find getfattr"
8927
8928         touch $DIR/$tfile
8929         ln -s $DIR/$tfile $DIR/${tfile}link
8930         getfattr -n trusted.lov $DIR/$tfile ||
8931                 error "lgetxattr on $DIR/$tfile failed"
8932         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8933                 grep -i "no such attr" ||
8934                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8935         rm -f $DIR/$tfile $DIR/${tfile}link
8936 }
8937 run_test 102i "lgetxattr test on symbolic link ============"
8938
8939 test_102j() {
8940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8941         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8942
8943         XINC=$(have_xattrs_include)
8944         setup_test102 "$RUNAS"
8945         chown $RUNAS_ID $DIR/$tdir
8946         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8947         cd $DIR/$tdir/$tdir
8948         compare_stripe_info1 "$RUNAS"
8949 }
8950 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8951
8952 test_102k() {
8953         [ -z "$(which setfattr 2>/dev/null)" ] &&
8954                 skip "could not find setfattr"
8955
8956         touch $DIR/$tfile
8957         # b22187 just check that does not crash for regular file.
8958         setfattr -n trusted.lov $DIR/$tfile
8959         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8960         local test_kdir=$DIR/$tdir
8961         test_mkdir $test_kdir
8962         local default_size=$($LFS getstripe -S $test_kdir)
8963         local default_count=$($LFS getstripe -c $test_kdir)
8964         local default_offset=$($LFS getstripe -i $test_kdir)
8965         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8966                 error 'dir setstripe failed'
8967         setfattr -n trusted.lov $test_kdir
8968         local stripe_size=$($LFS getstripe -S $test_kdir)
8969         local stripe_count=$($LFS getstripe -c $test_kdir)
8970         local stripe_offset=$($LFS getstripe -i $test_kdir)
8971         [ $stripe_size -eq $default_size ] ||
8972                 error "stripe size $stripe_size != $default_size"
8973         [ $stripe_count -eq $default_count ] ||
8974                 error "stripe count $stripe_count != $default_count"
8975         [ $stripe_offset -eq $default_offset ] ||
8976                 error "stripe offset $stripe_offset != $default_offset"
8977         rm -rf $DIR/$tfile $test_kdir
8978 }
8979 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8980
8981 test_102l() {
8982         [ -z "$(which getfattr 2>/dev/null)" ] &&
8983                 skip "could not find getfattr"
8984
8985         # LU-532 trusted. xattr is invisible to non-root
8986         local testfile=$DIR/$tfile
8987
8988         touch $testfile
8989
8990         echo "listxattr as user..."
8991         chown $RUNAS_ID $testfile
8992         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8993             grep -q "trusted" &&
8994                 error "$testfile trusted xattrs are user visible"
8995
8996         return 0;
8997 }
8998 run_test 102l "listxattr size test =================================="
8999
9000 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9001         local path=$DIR/$tfile
9002         touch $path
9003
9004         listxattr_size_check $path || error "listattr_size_check $path failed"
9005 }
9006 run_test 102m "Ensure listxattr fails on small bufffer ========"
9007
9008 cleanup_test102
9009
9010 getxattr() { # getxattr path name
9011         # Return the base64 encoding of the value of xattr name on path.
9012         local path=$1
9013         local name=$2
9014
9015         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9016         # file: $path
9017         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9018         #
9019         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9020
9021         getfattr --absolute-names --encoding=base64 --name=$name $path |
9022                 awk -F= -v name=$name '$1 == name {
9023                         print substr($0, index($0, "=") + 1);
9024         }'
9025 }
9026
9027 test_102n() { # LU-4101 mdt: protect internal xattrs
9028         [ -z "$(which setfattr 2>/dev/null)" ] &&
9029                 skip "could not find setfattr"
9030         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9031         then
9032                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9033         fi
9034
9035         local file0=$DIR/$tfile.0
9036         local file1=$DIR/$tfile.1
9037         local xattr0=$TMP/$tfile.0
9038         local xattr1=$TMP/$tfile.1
9039         local namelist="lov lma lmv link fid version som hsm"
9040         local name
9041         local value
9042
9043         rm -rf $file0 $file1 $xattr0 $xattr1
9044         touch $file0 $file1
9045
9046         # Get 'before' xattrs of $file1.
9047         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9048
9049         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9050                 namelist+=" lfsck_namespace"
9051         for name in $namelist; do
9052                 # Try to copy xattr from $file0 to $file1.
9053                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9054
9055                 setfattr --name=trusted.$name --value="$value" $file1 ||
9056                         error "setxattr 'trusted.$name' failed"
9057
9058                 # Try to set a garbage xattr.
9059                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9060
9061                 if [[ x$name == "xlov" ]]; then
9062                         setfattr --name=trusted.lov --value="$value" $file1 &&
9063                         error "setxattr invalid 'trusted.lov' success"
9064                 else
9065                         setfattr --name=trusted.$name --value="$value" $file1 ||
9066                                 error "setxattr invalid 'trusted.$name' failed"
9067                 fi
9068
9069                 # Try to remove the xattr from $file1. We don't care if this
9070                 # appears to succeed or fail, we just don't want there to be
9071                 # any changes or crashes.
9072                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9073         done
9074
9075         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9076         then
9077                 name="lfsck_ns"
9078                 # Try to copy xattr from $file0 to $file1.
9079                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9080
9081                 setfattr --name=trusted.$name --value="$value" $file1 ||
9082                         error "setxattr 'trusted.$name' failed"
9083
9084                 # Try to set a garbage xattr.
9085                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9086
9087                 setfattr --name=trusted.$name --value="$value" $file1 ||
9088                         error "setxattr 'trusted.$name' failed"
9089
9090                 # Try to remove the xattr from $file1. We don't care if this
9091                 # appears to succeed or fail, we just don't want there to be
9092                 # any changes or crashes.
9093                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9094         fi
9095
9096         # Get 'after' xattrs of file1.
9097         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9098
9099         if ! diff $xattr0 $xattr1; then
9100                 error "before and after xattrs of '$file1' differ"
9101         fi
9102
9103         rm -rf $file0 $file1 $xattr0 $xattr1
9104
9105         return 0
9106 }
9107 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9108
9109 test_102p() { # LU-4703 setxattr did not check ownership
9110         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9111                 skip "MDS needs to be at least 2.5.56"
9112
9113         local testfile=$DIR/$tfile
9114
9115         touch $testfile
9116
9117         echo "setfacl as user..."
9118         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9119         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9120
9121         echo "setfattr as user..."
9122         setfacl -m "u:$RUNAS_ID:---" $testfile
9123         $RUNAS setfattr -x system.posix_acl_access $testfile
9124         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9125 }
9126 run_test 102p "check setxattr(2) correctly fails without permission"
9127
9128 test_102q() {
9129         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9130                 skip "MDS needs to be at least 2.6.92"
9131
9132         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9133 }
9134 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9135
9136 test_102r() {
9137         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9138                 skip "MDS needs to be at least 2.6.93"
9139
9140         touch $DIR/$tfile || error "touch"
9141         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9142         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9143         rm $DIR/$tfile || error "rm"
9144
9145         #normal directory
9146         mkdir -p $DIR/$tdir || error "mkdir"
9147         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9148         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9149         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9150                 error "$testfile error deleting user.author1"
9151         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9152                 grep "user.$(basename $tdir)" &&
9153                 error "$tdir did not delete user.$(basename $tdir)"
9154         rmdir $DIR/$tdir || error "rmdir"
9155
9156         #striped directory
9157         test_mkdir $DIR/$tdir
9158         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9159         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9160         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9161                 error "$testfile error deleting user.author1"
9162         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9163                 grep "user.$(basename $tdir)" &&
9164                 error "$tdir did not delete user.$(basename $tdir)"
9165         rmdir $DIR/$tdir || error "rm striped dir"
9166 }
9167 run_test 102r "set EAs with empty values"
9168
9169 test_102s() {
9170         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9171                 skip "MDS needs to be at least 2.11.52"
9172
9173         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9174
9175         save_lustre_params client "llite.*.xattr_cache" > $save
9176
9177         for cache in 0 1; do
9178                 lctl set_param llite.*.xattr_cache=$cache
9179
9180                 rm -f $DIR/$tfile
9181                 touch $DIR/$tfile || error "touch"
9182                 for prefix in lustre security system trusted user; do
9183                         # Note getxattr() may fail with 'Operation not
9184                         # supported' or 'No such attribute' depending
9185                         # on prefix and cache.
9186                         getfattr -n $prefix.n102s $DIR/$tfile &&
9187                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9188                 done
9189         done
9190
9191         restore_lustre_params < $save
9192 }
9193 run_test 102s "getting nonexistent xattrs should fail"
9194
9195 test_102t() {
9196         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9197                 skip "MDS needs to be at least 2.11.52"
9198
9199         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9200
9201         save_lustre_params client "llite.*.xattr_cache" > $save
9202
9203         for cache in 0 1; do
9204                 lctl set_param llite.*.xattr_cache=$cache
9205
9206                 for buf_size in 0 256; do
9207                         rm -f $DIR/$tfile
9208                         touch $DIR/$tfile || error "touch"
9209                         setfattr -n user.multiop $DIR/$tfile
9210                         $MULTIOP $DIR/$tfile oa$buf_size ||
9211                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9212                 done
9213         done
9214
9215         restore_lustre_params < $save
9216 }
9217 run_test 102t "zero length xattr values handled correctly"
9218
9219 run_acl_subtest()
9220 {
9221     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9222     return $?
9223 }
9224
9225 test_103a() {
9226         [ "$UID" != 0 ] && skip "must run as root"
9227         $GSS && skip_env "could not run under gss"
9228         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9229                 skip_env "must have acl enabled"
9230         [ -z "$(which setfacl 2>/dev/null)" ] &&
9231                 skip_env "could not find setfacl"
9232         remote_mds_nodsh && skip "remote MDS with nodsh"
9233
9234         gpasswd -a daemon bin                           # LU-5641
9235         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9236
9237         declare -a identity_old
9238
9239         for num in $(seq $MDSCOUNT); do
9240                 switch_identity $num true || identity_old[$num]=$?
9241         done
9242
9243         SAVE_UMASK=$(umask)
9244         umask 0022
9245         mkdir -p $DIR/$tdir
9246         cd $DIR/$tdir
9247
9248         echo "performing cp ..."
9249         run_acl_subtest cp || error "run_acl_subtest cp failed"
9250         echo "performing getfacl-noacl..."
9251         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9252         echo "performing misc..."
9253         run_acl_subtest misc || error  "misc test failed"
9254         echo "performing permissions..."
9255         run_acl_subtest permissions || error "permissions failed"
9256         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9257         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9258                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9259                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9260         then
9261                 echo "performing permissions xattr..."
9262                 run_acl_subtest permissions_xattr ||
9263                         error "permissions_xattr failed"
9264         fi
9265         echo "performing setfacl..."
9266         run_acl_subtest setfacl || error  "setfacl test failed"
9267
9268         # inheritance test got from HP
9269         echo "performing inheritance..."
9270         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9271         chmod +x make-tree || error "chmod +x failed"
9272         run_acl_subtest inheritance || error "inheritance test failed"
9273         rm -f make-tree
9274
9275         echo "LU-974 ignore umask when acl is enabled..."
9276         run_acl_subtest 974 || error "LU-974 umask test failed"
9277         if [ $MDSCOUNT -ge 2 ]; then
9278                 run_acl_subtest 974_remote ||
9279                         error "LU-974 umask test failed under remote dir"
9280         fi
9281
9282         echo "LU-2561 newly created file is same size as directory..."
9283         if [ "$mds1_FSTYPE" != "zfs" ]; then
9284                 run_acl_subtest 2561 || error "LU-2561 test failed"
9285         else
9286                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9287         fi
9288
9289         run_acl_subtest 4924 || error "LU-4924 test failed"
9290
9291         cd $SAVE_PWD
9292         umask $SAVE_UMASK
9293
9294         for num in $(seq $MDSCOUNT); do
9295                 if [ "${identity_old[$num]}" = 1 ]; then
9296                         switch_identity $num false || identity_old[$num]=$?
9297                 fi
9298         done
9299 }
9300 run_test 103a "acl test"
9301
9302 test_103b() {
9303         declare -a pids
9304         local U
9305
9306         for U in {0..511}; do
9307                 {
9308                 local O=$(printf "%04o" $U)
9309
9310                 umask $(printf "%04o" $((511 ^ $O)))
9311                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9312                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9313
9314                 (( $S == ($O & 0666) )) ||
9315                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9316
9317                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9318                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9319                 (( $S == ($O & 0666) )) ||
9320                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9321
9322                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9323                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9324                 (( $S == ($O & 0666) )) ||
9325                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9326                 rm -f $DIR/$tfile.[smp]$0
9327                 } &
9328                 local pid=$!
9329
9330                 # limit the concurrently running threads to 64. LU-11878
9331                 local idx=$((U % 64))
9332                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9333                 pids[idx]=$pid
9334         done
9335         wait
9336 }
9337 run_test 103b "umask lfs setstripe"
9338
9339 test_103c() {
9340         mkdir -p $DIR/$tdir
9341         cp -rp $DIR/$tdir $DIR/$tdir.bak
9342
9343         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9344                 error "$DIR/$tdir shouldn't contain default ACL"
9345         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9346                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9347         true
9348 }
9349 run_test 103c "'cp -rp' won't set empty acl"
9350
9351 test_104a() {
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         touch $DIR/$tfile
9355         lfs df || error "lfs df failed"
9356         lfs df -ih || error "lfs df -ih failed"
9357         lfs df -h $DIR || error "lfs df -h $DIR failed"
9358         lfs df -i $DIR || error "lfs df -i $DIR failed"
9359         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9360         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9361
9362         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9363         lctl --device %$OSC deactivate
9364         lfs df || error "lfs df with deactivated OSC failed"
9365         lctl --device %$OSC activate
9366         # wait the osc back to normal
9367         wait_osc_import_ready client ost
9368
9369         lfs df || error "lfs df with reactivated OSC failed"
9370         rm -f $DIR/$tfile
9371 }
9372 run_test 104a "lfs df [-ih] [path] test ========================="
9373
9374 test_104b() {
9375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9376         [ $RUNAS_ID -eq $UID ] &&
9377                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9378
9379         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9380                         grep "Permission denied" | wc -l)))
9381         if [ $denied_cnt -ne 0 ]; then
9382                 error "lfs check servers test failed"
9383         fi
9384 }
9385 run_test 104b "$RUNAS lfs check servers test ===================="
9386
9387 test_105a() {
9388         # doesn't work on 2.4 kernels
9389         touch $DIR/$tfile
9390         if $(flock_is_enabled); then
9391                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9392         else
9393                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9394         fi
9395         rm -f $DIR/$tfile
9396 }
9397 run_test 105a "flock when mounted without -o flock test ========"
9398
9399 test_105b() {
9400         touch $DIR/$tfile
9401         if $(flock_is_enabled); then
9402                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9403         else
9404                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9405         fi
9406         rm -f $DIR/$tfile
9407 }
9408 run_test 105b "fcntl when mounted without -o flock test ========"
9409
9410 test_105c() {
9411         touch $DIR/$tfile
9412         if $(flock_is_enabled); then
9413                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9414         else
9415                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9416         fi
9417         rm -f $DIR/$tfile
9418 }
9419 run_test 105c "lockf when mounted without -o flock test"
9420
9421 test_105d() { # bug 15924
9422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9423
9424         test_mkdir $DIR/$tdir
9425         flock_is_enabled || skip_env "mount w/o flock enabled"
9426         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9427         $LCTL set_param fail_loc=0x80000315
9428         flocks_test 2 $DIR/$tdir
9429 }
9430 run_test 105d "flock race (should not freeze) ========"
9431
9432 test_105e() { # bug 22660 && 22040
9433         flock_is_enabled || skip_env "mount w/o flock enabled"
9434
9435         touch $DIR/$tfile
9436         flocks_test 3 $DIR/$tfile
9437 }
9438 run_test 105e "Two conflicting flocks from same process"
9439
9440 test_106() { #bug 10921
9441         test_mkdir $DIR/$tdir
9442         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9443         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9444 }
9445 run_test 106 "attempt exec of dir followed by chown of that dir"
9446
9447 test_107() {
9448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9449
9450         CDIR=`pwd`
9451         local file=core
9452
9453         cd $DIR
9454         rm -f $file
9455
9456         local save_pattern=$(sysctl -n kernel.core_pattern)
9457         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9458         sysctl -w kernel.core_pattern=$file
9459         sysctl -w kernel.core_uses_pid=0
9460
9461         ulimit -c unlimited
9462         sleep 60 &
9463         SLEEPPID=$!
9464
9465         sleep 1
9466
9467         kill -s 11 $SLEEPPID
9468         wait $SLEEPPID
9469         if [ -e $file ]; then
9470                 size=`stat -c%s $file`
9471                 [ $size -eq 0 ] && error "Fail to create core file $file"
9472         else
9473                 error "Fail to create core file $file"
9474         fi
9475         rm -f $file
9476         sysctl -w kernel.core_pattern=$save_pattern
9477         sysctl -w kernel.core_uses_pid=$save_uses_pid
9478         cd $CDIR
9479 }
9480 run_test 107 "Coredump on SIG"
9481
9482 test_110() {
9483         test_mkdir $DIR/$tdir
9484         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9485         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9486                 error "mkdir with 256 char should fail, but did not"
9487         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9488                 error "create with 255 char failed"
9489         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9490                 error "create with 256 char should fail, but did not"
9491
9492         ls -l $DIR/$tdir
9493         rm -rf $DIR/$tdir
9494 }
9495 run_test 110 "filename length checking"
9496
9497 #
9498 # Purpose: To verify dynamic thread (OSS) creation.
9499 #
9500 test_115() {
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502         remote_ost_nodsh && skip "remote OST with nodsh"
9503
9504         # Lustre does not stop service threads once they are started.
9505         # Reset number of running threads to default.
9506         stopall
9507         setupall
9508
9509         local OSTIO_pre
9510         local save_params="$TMP/sanity-$TESTNAME.parameters"
9511
9512         # Get ll_ost_io count before I/O
9513         OSTIO_pre=$(do_facet ost1 \
9514                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9515         # Exit if lustre is not running (ll_ost_io not running).
9516         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9517
9518         echo "Starting with $OSTIO_pre threads"
9519         local thread_max=$((OSTIO_pre * 2))
9520         local rpc_in_flight=$((thread_max * 2))
9521         # Number of I/O Process proposed to be started.
9522         local nfiles
9523         local facets=$(get_facets OST)
9524
9525         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9526         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9527
9528         # Set in_flight to $rpc_in_flight
9529         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9530                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9531         nfiles=${rpc_in_flight}
9532         # Set ost thread_max to $thread_max
9533         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9534
9535         # 5 Minutes should be sufficient for max number of OSS
9536         # threads(thread_max) to be created.
9537         local timeout=300
9538
9539         # Start I/O.
9540         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9541         test_mkdir $DIR/$tdir
9542         for i in $(seq $nfiles); do
9543                 local file=$DIR/$tdir/${tfile}-$i
9544                 $LFS setstripe -c -1 -i 0 $file
9545                 ($WTL $file $timeout)&
9546         done
9547
9548         # I/O Started - Wait for thread_started to reach thread_max or report
9549         # error if thread_started is more than thread_max.
9550         echo "Waiting for thread_started to reach thread_max"
9551         local thread_started=0
9552         local end_time=$((SECONDS + timeout))
9553
9554         while [ $SECONDS -le $end_time ] ; do
9555                 echo -n "."
9556                 # Get ost i/o thread_started count.
9557                 thread_started=$(do_facet ost1 \
9558                         "$LCTL get_param \
9559                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9560                 # Break out if thread_started is equal/greater than thread_max
9561                 if [[ $thread_started -ge $thread_max ]]; then
9562                         echo ll_ost_io thread_started $thread_started, \
9563                                 equal/greater than thread_max $thread_max
9564                         break
9565                 fi
9566                 sleep 1
9567         done
9568
9569         # Cleanup - We have the numbers, Kill i/o jobs if running.
9570         jobcount=($(jobs -p))
9571         for i in $(seq 0 $((${#jobcount[@]}-1)))
9572         do
9573                 kill -9 ${jobcount[$i]}
9574                 if [ $? -ne 0 ] ; then
9575                         echo Warning: \
9576                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9577                 fi
9578         done
9579
9580         # Cleanup files left by WTL binary.
9581         for i in $(seq $nfiles); do
9582                 local file=$DIR/$tdir/${tfile}-$i
9583                 rm -rf $file
9584                 if [ $? -ne 0 ] ; then
9585                         echo "Warning: Failed to delete file $file"
9586                 fi
9587         done
9588
9589         restore_lustre_params <$save_params
9590         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9591
9592         # Error out if no new thread has started or Thread started is greater
9593         # than thread max.
9594         if [[ $thread_started -le $OSTIO_pre ||
9595                         $thread_started -gt $thread_max ]]; then
9596                 error "ll_ost_io: thread_started $thread_started" \
9597                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9598                       "No new thread started or thread started greater " \
9599                       "than thread_max."
9600         fi
9601 }
9602 run_test 115 "verify dynamic thread creation===================="
9603
9604 free_min_max () {
9605         wait_delete_completed
9606         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9607         echo "OST kbytes available: ${AVAIL[@]}"
9608         MAXV=${AVAIL[0]}
9609         MAXI=0
9610         MINV=${AVAIL[0]}
9611         MINI=0
9612         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9613                 #echo OST $i: ${AVAIL[i]}kb
9614                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9615                         MAXV=${AVAIL[i]}
9616                         MAXI=$i
9617                 fi
9618                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9619                         MINV=${AVAIL[i]}
9620                         MINI=$i
9621                 fi
9622         done
9623         echo "Min free space: OST $MINI: $MINV"
9624         echo "Max free space: OST $MAXI: $MAXV"
9625 }
9626
9627 test_116a() { # was previously test_116()
9628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9630         remote_mds_nodsh && skip "remote MDS with nodsh"
9631
9632         echo -n "Free space priority "
9633         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9634                 head -n1
9635         declare -a AVAIL
9636         free_min_max
9637
9638         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9639         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9640         trap simple_cleanup_common EXIT
9641
9642         # Check if we need to generate uneven OSTs
9643         test_mkdir -p $DIR/$tdir/OST${MINI}
9644         local FILL=$((MINV / 4))
9645         local DIFF=$((MAXV - MINV))
9646         local DIFF2=$((DIFF * 100 / MINV))
9647
9648         local threshold=$(do_facet $SINGLEMDS \
9649                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9650         threshold=${threshold%%%}
9651         echo -n "Check for uneven OSTs: "
9652         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9653
9654         if [[ $DIFF2 -gt $threshold ]]; then
9655                 echo "ok"
9656                 echo "Don't need to fill OST$MINI"
9657         else
9658                 # generate uneven OSTs. Write 2% over the QOS threshold value
9659                 echo "no"
9660                 DIFF=$((threshold - DIFF2 + 2))
9661                 DIFF2=$((MINV * DIFF / 100))
9662                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9663                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9664                         error "setstripe failed"
9665                 DIFF=$((DIFF2 / 2048))
9666                 i=0
9667                 while [ $i -lt $DIFF ]; do
9668                         i=$((i + 1))
9669                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9670                                 bs=2M count=1 2>/dev/null
9671                         echo -n .
9672                 done
9673                 echo .
9674                 sync
9675                 sleep_maxage
9676                 free_min_max
9677         fi
9678
9679         DIFF=$((MAXV - MINV))
9680         DIFF2=$((DIFF * 100 / MINV))
9681         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9682         if [ $DIFF2 -gt $threshold ]; then
9683                 echo "ok"
9684         else
9685                 echo "failed - QOS mode won't be used"
9686                 simple_cleanup_common
9687                 skip "QOS imbalance criteria not met"
9688         fi
9689
9690         MINI1=$MINI
9691         MINV1=$MINV
9692         MAXI1=$MAXI
9693         MAXV1=$MAXV
9694
9695         # now fill using QOS
9696         $LFS setstripe -c 1 $DIR/$tdir
9697         FILL=$((FILL / 200))
9698         if [ $FILL -gt 600 ]; then
9699                 FILL=600
9700         fi
9701         echo "writing $FILL files to QOS-assigned OSTs"
9702         i=0
9703         while [ $i -lt $FILL ]; do
9704                 i=$((i + 1))
9705                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9706                         count=1 2>/dev/null
9707                 echo -n .
9708         done
9709         echo "wrote $i 200k files"
9710         sync
9711         sleep_maxage
9712
9713         echo "Note: free space may not be updated, so measurements might be off"
9714         free_min_max
9715         DIFF2=$((MAXV - MINV))
9716         echo "free space delta: orig $DIFF final $DIFF2"
9717         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9718         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9719         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9720         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9721         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9722         if [[ $DIFF -gt 0 ]]; then
9723                 FILL=$((DIFF2 * 100 / DIFF - 100))
9724                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9725         fi
9726
9727         # Figure out which files were written where
9728         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9729                awk '/'$MINI1': / {print $2; exit}')
9730         echo $UUID
9731         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9732         echo "$MINC files created on smaller OST $MINI1"
9733         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9734                awk '/'$MAXI1': / {print $2; exit}')
9735         echo $UUID
9736         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9737         echo "$MAXC files created on larger OST $MAXI1"
9738         if [[ $MINC -gt 0 ]]; then
9739                 FILL=$((MAXC * 100 / MINC - 100))
9740                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9741         fi
9742         [[ $MAXC -gt $MINC ]] ||
9743                 error_ignore LU-9 "stripe QOS didn't balance free space"
9744         simple_cleanup_common
9745 }
9746 run_test 116a "stripe QOS: free space balance ==================="
9747
9748 test_116b() { # LU-2093
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         remote_mds_nodsh && skip "remote MDS with nodsh"
9751
9752 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9753         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9754                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9755         [ -z "$old_rr" ] && skip "no QOS"
9756         do_facet $SINGLEMDS lctl set_param \
9757                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9758         mkdir -p $DIR/$tdir
9759         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9760         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9761         do_facet $SINGLEMDS lctl set_param fail_loc=0
9762         rm -rf $DIR/$tdir
9763         do_facet $SINGLEMDS lctl set_param \
9764                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9765 }
9766 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9767
9768 test_117() # bug 10891
9769 {
9770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9771
9772         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9773         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9774         lctl set_param fail_loc=0x21e
9775         > $DIR/$tfile || error "truncate failed"
9776         lctl set_param fail_loc=0
9777         echo "Truncate succeeded."
9778         rm -f $DIR/$tfile
9779 }
9780 run_test 117 "verify osd extend =========="
9781
9782 NO_SLOW_RESENDCOUNT=4
9783 export OLD_RESENDCOUNT=""
9784 set_resend_count () {
9785         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9786         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9787         lctl set_param -n $PROC_RESENDCOUNT $1
9788         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9789 }
9790
9791 # for reduce test_118* time (b=14842)
9792 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9793
9794 # Reset async IO behavior after error case
9795 reset_async() {
9796         FILE=$DIR/reset_async
9797
9798         # Ensure all OSCs are cleared
9799         $LFS setstripe -c -1 $FILE
9800         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9801         sync
9802         rm $FILE
9803 }
9804
9805 test_118a() #bug 11710
9806 {
9807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9808
9809         reset_async
9810
9811         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9812         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9813         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9814
9815         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9816                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9817                 return 1;
9818         fi
9819         rm -f $DIR/$tfile
9820 }
9821 run_test 118a "verify O_SYNC works =========="
9822
9823 test_118b()
9824 {
9825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9826         remote_ost_nodsh && skip "remote OST with nodsh"
9827
9828         reset_async
9829
9830         #define OBD_FAIL_SRV_ENOENT 0x217
9831         set_nodes_failloc "$(osts_nodes)" 0x217
9832         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9833         RC=$?
9834         set_nodes_failloc "$(osts_nodes)" 0
9835         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9836         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9837                     grep -c writeback)
9838
9839         if [[ $RC -eq 0 ]]; then
9840                 error "Must return error due to dropped pages, rc=$RC"
9841                 return 1;
9842         fi
9843
9844         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9845                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9846                 return 1;
9847         fi
9848
9849         echo "Dirty pages not leaked on ENOENT"
9850
9851         # Due to the above error the OSC will issue all RPCs syncronously
9852         # until a subsequent RPC completes successfully without error.
9853         $MULTIOP $DIR/$tfile Ow4096yc
9854         rm -f $DIR/$tfile
9855
9856         return 0
9857 }
9858 run_test 118b "Reclaim dirty pages on fatal error =========="
9859
9860 test_118c()
9861 {
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863
9864         # for 118c, restore the original resend count, LU-1940
9865         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9866                                 set_resend_count $OLD_RESENDCOUNT
9867         remote_ost_nodsh && skip "remote OST with nodsh"
9868
9869         reset_async
9870
9871         #define OBD_FAIL_OST_EROFS               0x216
9872         set_nodes_failloc "$(osts_nodes)" 0x216
9873
9874         # multiop should block due to fsync until pages are written
9875         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9876         MULTIPID=$!
9877         sleep 1
9878
9879         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9880                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9881         fi
9882
9883         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9884                     grep -c writeback)
9885         if [[ $WRITEBACK -eq 0 ]]; then
9886                 error "No page in writeback, writeback=$WRITEBACK"
9887         fi
9888
9889         set_nodes_failloc "$(osts_nodes)" 0
9890         wait $MULTIPID
9891         RC=$?
9892         if [[ $RC -ne 0 ]]; then
9893                 error "Multiop fsync failed, rc=$RC"
9894         fi
9895
9896         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9897         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9898                     grep -c writeback)
9899         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9900                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9901         fi
9902
9903         rm -f $DIR/$tfile
9904         echo "Dirty pages flushed via fsync on EROFS"
9905         return 0
9906 }
9907 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9908
9909 # continue to use small resend count to reduce test_118* time (b=14842)
9910 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9911
9912 test_118d()
9913 {
9914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9915         remote_ost_nodsh && skip "remote OST with nodsh"
9916
9917         reset_async
9918
9919         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9920         set_nodes_failloc "$(osts_nodes)" 0x214
9921         # multiop should block due to fsync until pages are written
9922         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9923         MULTIPID=$!
9924         sleep 1
9925
9926         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9927                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9928         fi
9929
9930         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9931                     grep -c writeback)
9932         if [[ $WRITEBACK -eq 0 ]]; then
9933                 error "No page in writeback, writeback=$WRITEBACK"
9934         fi
9935
9936         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9937         set_nodes_failloc "$(osts_nodes)" 0
9938
9939         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9940         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9941                     grep -c writeback)
9942         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9943                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9944         fi
9945
9946         rm -f $DIR/$tfile
9947         echo "Dirty pages gaurenteed flushed via fsync"
9948         return 0
9949 }
9950 run_test 118d "Fsync validation inject a delay of the bulk =========="
9951
9952 test_118f() {
9953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9954
9955         reset_async
9956
9957         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9958         lctl set_param fail_loc=0x8000040a
9959
9960         # Should simulate EINVAL error which is fatal
9961         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9962         RC=$?
9963         if [[ $RC -eq 0 ]]; then
9964                 error "Must return error due to dropped pages, rc=$RC"
9965         fi
9966
9967         lctl set_param fail_loc=0x0
9968
9969         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9970         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9971         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9972                     grep -c writeback)
9973         if [[ $LOCKED -ne 0 ]]; then
9974                 error "Locked pages remain in cache, locked=$LOCKED"
9975         fi
9976
9977         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9978                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9979         fi
9980
9981         rm -f $DIR/$tfile
9982         echo "No pages locked after fsync"
9983
9984         reset_async
9985         return 0
9986 }
9987 run_test 118f "Simulate unrecoverable OSC side error =========="
9988
9989 test_118g() {
9990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9991
9992         reset_async
9993
9994         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9995         lctl set_param fail_loc=0x406
9996
9997         # simulate local -ENOMEM
9998         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9999         RC=$?
10000
10001         lctl set_param fail_loc=0
10002         if [[ $RC -eq 0 ]]; then
10003                 error "Must return error due to dropped pages, rc=$RC"
10004         fi
10005
10006         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10007         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10008         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10009                         grep -c writeback)
10010         if [[ $LOCKED -ne 0 ]]; then
10011                 error "Locked pages remain in cache, locked=$LOCKED"
10012         fi
10013
10014         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10015                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10016         fi
10017
10018         rm -f $DIR/$tfile
10019         echo "No pages locked after fsync"
10020
10021         reset_async
10022         return 0
10023 }
10024 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10025
10026 test_118h() {
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028         remote_ost_nodsh && skip "remote OST with nodsh"
10029
10030         reset_async
10031
10032         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10033         set_nodes_failloc "$(osts_nodes)" 0x20e
10034         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10035         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10036         RC=$?
10037
10038         set_nodes_failloc "$(osts_nodes)" 0
10039         if [[ $RC -eq 0 ]]; then
10040                 error "Must return error due to dropped pages, rc=$RC"
10041         fi
10042
10043         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10044         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10045         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10046                     grep -c writeback)
10047         if [[ $LOCKED -ne 0 ]]; then
10048                 error "Locked pages remain in cache, locked=$LOCKED"
10049         fi
10050
10051         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10052                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10053         fi
10054
10055         rm -f $DIR/$tfile
10056         echo "No pages locked after fsync"
10057
10058         return 0
10059 }
10060 run_test 118h "Verify timeout in handling recoverables errors  =========="
10061
10062 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10063
10064 test_118i() {
10065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10066         remote_ost_nodsh && skip "remote OST with nodsh"
10067
10068         reset_async
10069
10070         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10071         set_nodes_failloc "$(osts_nodes)" 0x20e
10072
10073         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10074         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10075         PID=$!
10076         sleep 5
10077         set_nodes_failloc "$(osts_nodes)" 0
10078
10079         wait $PID
10080         RC=$?
10081         if [[ $RC -ne 0 ]]; then
10082                 error "got error, but should be not, rc=$RC"
10083         fi
10084
10085         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10086         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10087         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10088         if [[ $LOCKED -ne 0 ]]; then
10089                 error "Locked pages remain in cache, locked=$LOCKED"
10090         fi
10091
10092         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10093                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10094         fi
10095
10096         rm -f $DIR/$tfile
10097         echo "No pages locked after fsync"
10098
10099         return 0
10100 }
10101 run_test 118i "Fix error before timeout in recoverable error  =========="
10102
10103 [ "$SLOW" = "no" ] && set_resend_count 4
10104
10105 test_118j() {
10106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10107         remote_ost_nodsh && skip "remote OST with nodsh"
10108
10109         reset_async
10110
10111         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10112         set_nodes_failloc "$(osts_nodes)" 0x220
10113
10114         # return -EIO from OST
10115         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10116         RC=$?
10117         set_nodes_failloc "$(osts_nodes)" 0x0
10118         if [[ $RC -eq 0 ]]; then
10119                 error "Must return error due to dropped pages, rc=$RC"
10120         fi
10121
10122         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10123         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10124         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10125         if [[ $LOCKED -ne 0 ]]; then
10126                 error "Locked pages remain in cache, locked=$LOCKED"
10127         fi
10128
10129         # in recoverable error on OST we want resend and stay until it finished
10130         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10131                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10132         fi
10133
10134         rm -f $DIR/$tfile
10135         echo "No pages locked after fsync"
10136
10137         return 0
10138 }
10139 run_test 118j "Simulate unrecoverable OST side error =========="
10140
10141 test_118k()
10142 {
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144         remote_ost_nodsh && skip "remote OSTs with nodsh"
10145
10146         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10147         set_nodes_failloc "$(osts_nodes)" 0x20e
10148         test_mkdir $DIR/$tdir
10149
10150         for ((i=0;i<10;i++)); do
10151                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10152                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10153                 SLEEPPID=$!
10154                 sleep 0.500s
10155                 kill $SLEEPPID
10156                 wait $SLEEPPID
10157         done
10158
10159         set_nodes_failloc "$(osts_nodes)" 0
10160         rm -rf $DIR/$tdir
10161 }
10162 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10163
10164 test_118l() # LU-646
10165 {
10166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10167
10168         test_mkdir $DIR/$tdir
10169         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10170         rm -rf $DIR/$tdir
10171 }
10172 run_test 118l "fsync dir"
10173
10174 test_118m() # LU-3066
10175 {
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177
10178         test_mkdir $DIR/$tdir
10179         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10180         rm -rf $DIR/$tdir
10181 }
10182 run_test 118m "fdatasync dir ========="
10183
10184 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10185
10186 test_118n()
10187 {
10188         local begin
10189         local end
10190
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         remote_ost_nodsh && skip "remote OSTs with nodsh"
10193
10194         # Sleep to avoid a cached response.
10195         #define OBD_STATFS_CACHE_SECONDS 1
10196         sleep 2
10197
10198         # Inject a 10 second delay in the OST_STATFS handler.
10199         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10200         set_nodes_failloc "$(osts_nodes)" 0x242
10201
10202         begin=$SECONDS
10203         stat --file-system $MOUNT > /dev/null
10204         end=$SECONDS
10205
10206         set_nodes_failloc "$(osts_nodes)" 0
10207
10208         if ((end - begin > 20)); then
10209             error "statfs took $((end - begin)) seconds, expected 10"
10210         fi
10211 }
10212 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10213
10214 test_119a() # bug 11737
10215 {
10216         BSIZE=$((512 * 1024))
10217         directio write $DIR/$tfile 0 1 $BSIZE
10218         # We ask to read two blocks, which is more than a file size.
10219         # directio will indicate an error when requested and actual
10220         # sizes aren't equeal (a normal situation in this case) and
10221         # print actual read amount.
10222         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10223         if [ "$NOB" != "$BSIZE" ]; then
10224                 error "read $NOB bytes instead of $BSIZE"
10225         fi
10226         rm -f $DIR/$tfile
10227 }
10228 run_test 119a "Short directIO read must return actual read amount"
10229
10230 test_119b() # bug 11737
10231 {
10232         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10233
10234         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10235         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10236         sync
10237         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10238                 error "direct read failed"
10239         rm -f $DIR/$tfile
10240 }
10241 run_test 119b "Sparse directIO read must return actual read amount"
10242
10243 test_119c() # bug 13099
10244 {
10245         BSIZE=1048576
10246         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10247         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10248         rm -f $DIR/$tfile
10249 }
10250 run_test 119c "Testing for direct read hitting hole"
10251
10252 test_119d() # bug 15950
10253 {
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255
10256         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10257         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10258         BSIZE=1048576
10259         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10260         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10261         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10262         lctl set_param fail_loc=0x40d
10263         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10264         pid_dio=$!
10265         sleep 1
10266         cat $DIR/$tfile > /dev/null &
10267         lctl set_param fail_loc=0
10268         pid_reads=$!
10269         wait $pid_dio
10270         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10271         sleep 2
10272         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10273         error "the read rpcs have not completed in 2s"
10274         rm -f $DIR/$tfile
10275         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10276 }
10277 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10278
10279 test_120a() {
10280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10281         remote_mds_nodsh && skip "remote MDS with nodsh"
10282         test_mkdir -i0 -c1 $DIR/$tdir
10283         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10284                 skip_env "no early lock cancel on server"
10285
10286         lru_resize_disable mdc
10287         lru_resize_disable osc
10288         cancel_lru_locks mdc
10289         # asynchronous object destroy at MDT could cause bl ast to client
10290         cancel_lru_locks osc
10291
10292         stat $DIR/$tdir > /dev/null
10293         can1=$(do_facet mds1 \
10294                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10295                awk '/ldlm_cancel/ {print $2}')
10296         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10297                awk '/ldlm_bl_callback/ {print $2}')
10298         test_mkdir -i0 -c1 $DIR/$tdir/d1
10299         can2=$(do_facet mds1 \
10300                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10301                awk '/ldlm_cancel/ {print $2}')
10302         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10303                awk '/ldlm_bl_callback/ {print $2}')
10304         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10305         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10306         lru_resize_enable mdc
10307         lru_resize_enable osc
10308 }
10309 run_test 120a "Early Lock Cancel: mkdir test"
10310
10311 test_120b() {
10312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10313         remote_mds_nodsh && skip "remote MDS with nodsh"
10314         test_mkdir $DIR/$tdir
10315         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10316                 skip_env "no early lock cancel on server"
10317
10318         lru_resize_disable mdc
10319         lru_resize_disable osc
10320         cancel_lru_locks mdc
10321         stat $DIR/$tdir > /dev/null
10322         can1=$(do_facet $SINGLEMDS \
10323                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10324                awk '/ldlm_cancel/ {print $2}')
10325         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10326                awk '/ldlm_bl_callback/ {print $2}')
10327         touch $DIR/$tdir/f1
10328         can2=$(do_facet $SINGLEMDS \
10329                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10330                awk '/ldlm_cancel/ {print $2}')
10331         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10332                awk '/ldlm_bl_callback/ {print $2}')
10333         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10334         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10335         lru_resize_enable mdc
10336         lru_resize_enable osc
10337 }
10338 run_test 120b "Early Lock Cancel: create test"
10339
10340 test_120c() {
10341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10342         remote_mds_nodsh && skip "remote MDS with nodsh"
10343         test_mkdir -i0 -c1 $DIR/$tdir
10344         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10345                 skip "no early lock cancel on server"
10346
10347         lru_resize_disable mdc
10348         lru_resize_disable osc
10349         test_mkdir -i0 -c1 $DIR/$tdir/d1
10350         test_mkdir -i0 -c1 $DIR/$tdir/d2
10351         touch $DIR/$tdir/d1/f1
10352         cancel_lru_locks mdc
10353         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10354         can1=$(do_facet mds1 \
10355                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10356                awk '/ldlm_cancel/ {print $2}')
10357         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10358                awk '/ldlm_bl_callback/ {print $2}')
10359         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10360         can2=$(do_facet mds1 \
10361                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10362                awk '/ldlm_cancel/ {print $2}')
10363         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10364                awk '/ldlm_bl_callback/ {print $2}')
10365         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10366         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10367         lru_resize_enable mdc
10368         lru_resize_enable osc
10369 }
10370 run_test 120c "Early Lock Cancel: link test"
10371
10372 test_120d() {
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374         remote_mds_nodsh && skip "remote MDS with nodsh"
10375         test_mkdir -i0 -c1 $DIR/$tdir
10376         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10377                 skip_env "no early lock cancel on server"
10378
10379         lru_resize_disable mdc
10380         lru_resize_disable osc
10381         touch $DIR/$tdir
10382         cancel_lru_locks mdc
10383         stat $DIR/$tdir > /dev/null
10384         can1=$(do_facet mds1 \
10385                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10386                awk '/ldlm_cancel/ {print $2}')
10387         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10388                awk '/ldlm_bl_callback/ {print $2}')
10389         chmod a+x $DIR/$tdir
10390         can2=$(do_facet mds1 \
10391                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10392                awk '/ldlm_cancel/ {print $2}')
10393         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10394                awk '/ldlm_bl_callback/ {print $2}')
10395         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10396         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10397         lru_resize_enable mdc
10398         lru_resize_enable osc
10399 }
10400 run_test 120d "Early Lock Cancel: setattr test"
10401
10402 test_120e() {
10403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10404         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10405                 skip_env "no early lock cancel on server"
10406         remote_mds_nodsh && skip "remote MDS with nodsh"
10407
10408         local dlmtrace_set=false
10409
10410         test_mkdir -i0 -c1 $DIR/$tdir
10411         lru_resize_disable mdc
10412         lru_resize_disable osc
10413         ! $LCTL get_param debug | grep -q dlmtrace &&
10414                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10415         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10416         cancel_lru_locks mdc
10417         cancel_lru_locks osc
10418         dd if=$DIR/$tdir/f1 of=/dev/null
10419         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10420         # XXX client can not do early lock cancel of OST lock
10421         # during unlink (LU-4206), so cancel osc lock now.
10422         sleep 2
10423         cancel_lru_locks osc
10424         can1=$(do_facet mds1 \
10425                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10426                awk '/ldlm_cancel/ {print $2}')
10427         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10428                awk '/ldlm_bl_callback/ {print $2}')
10429         unlink $DIR/$tdir/f1
10430         sleep 5
10431         can2=$(do_facet mds1 \
10432                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10433                awk '/ldlm_cancel/ {print $2}')
10434         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10435                awk '/ldlm_bl_callback/ {print $2}')
10436         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10437                 $LCTL dk $TMP/cancel.debug.txt
10438         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10439                 $LCTL dk $TMP/blocking.debug.txt
10440         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10441         lru_resize_enable mdc
10442         lru_resize_enable osc
10443 }
10444 run_test 120e "Early Lock Cancel: unlink test"
10445
10446 test_120f() {
10447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10448         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10449                 skip_env "no early lock cancel on server"
10450         remote_mds_nodsh && skip "remote MDS with nodsh"
10451
10452         test_mkdir -i0 -c1 $DIR/$tdir
10453         lru_resize_disable mdc
10454         lru_resize_disable osc
10455         test_mkdir -i0 -c1 $DIR/$tdir/d1
10456         test_mkdir -i0 -c1 $DIR/$tdir/d2
10457         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10458         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10459         cancel_lru_locks mdc
10460         cancel_lru_locks osc
10461         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10462         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10463         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10464         # XXX client can not do early lock cancel of OST lock
10465         # during rename (LU-4206), so cancel osc lock now.
10466         sleep 2
10467         cancel_lru_locks osc
10468         can1=$(do_facet mds1 \
10469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10470                awk '/ldlm_cancel/ {print $2}')
10471         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10472                awk '/ldlm_bl_callback/ {print $2}')
10473         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10474         sleep 5
10475         can2=$(do_facet mds1 \
10476                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10477                awk '/ldlm_cancel/ {print $2}')
10478         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10479                awk '/ldlm_bl_callback/ {print $2}')
10480         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10481         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10482         lru_resize_enable mdc
10483         lru_resize_enable osc
10484 }
10485 run_test 120f "Early Lock Cancel: rename test"
10486
10487 test_120g() {
10488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10489         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10490                 skip_env "no early lock cancel on server"
10491         remote_mds_nodsh && skip "remote MDS with nodsh"
10492
10493         lru_resize_disable mdc
10494         lru_resize_disable osc
10495         count=10000
10496         echo create $count files
10497         test_mkdir $DIR/$tdir
10498         cancel_lru_locks mdc
10499         cancel_lru_locks osc
10500         t0=$(date +%s)
10501
10502         can0=$(do_facet $SINGLEMDS \
10503                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10504                awk '/ldlm_cancel/ {print $2}')
10505         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10506                awk '/ldlm_bl_callback/ {print $2}')
10507         createmany -o $DIR/$tdir/f $count
10508         sync
10509         can1=$(do_facet $SINGLEMDS \
10510                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10511                awk '/ldlm_cancel/ {print $2}')
10512         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10513                awk '/ldlm_bl_callback/ {print $2}')
10514         t1=$(date +%s)
10515         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10516         echo rm $count files
10517         rm -r $DIR/$tdir
10518         sync
10519         can2=$(do_facet $SINGLEMDS \
10520                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10521                awk '/ldlm_cancel/ {print $2}')
10522         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10523                awk '/ldlm_bl_callback/ {print $2}')
10524         t2=$(date +%s)
10525         echo total: $count removes in $((t2-t1))
10526         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10527         sleep 2
10528         # wait for commitment of removal
10529         lru_resize_enable mdc
10530         lru_resize_enable osc
10531 }
10532 run_test 120g "Early Lock Cancel: performance test"
10533
10534 test_121() { #bug #10589
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536
10537         rm -rf $DIR/$tfile
10538         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10539 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10540         lctl set_param fail_loc=0x310
10541         cancel_lru_locks osc > /dev/null
10542         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10543         lctl set_param fail_loc=0
10544         [[ $reads -eq $writes ]] ||
10545                 error "read $reads blocks, must be $writes blocks"
10546 }
10547 run_test 121 "read cancel race ========="
10548
10549 test_123a() { # was test 123, statahead(bug 11401)
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551
10552         SLOWOK=0
10553         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10554                 log "testing UP system. Performance may be lower than expected."
10555                 SLOWOK=1
10556         fi
10557
10558         rm -rf $DIR/$tdir
10559         test_mkdir $DIR/$tdir
10560         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10561         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10562         MULT=10
10563         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10564                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10565
10566                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10567                 lctl set_param -n llite.*.statahead_max 0
10568                 lctl get_param llite.*.statahead_max
10569                 cancel_lru_locks mdc
10570                 cancel_lru_locks osc
10571                 stime=`date +%s`
10572                 time ls -l $DIR/$tdir | wc -l
10573                 etime=`date +%s`
10574                 delta=$((etime - stime))
10575                 log "ls $i files without statahead: $delta sec"
10576                 lctl set_param llite.*.statahead_max=$max
10577
10578                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10579                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10580                 cancel_lru_locks mdc
10581                 cancel_lru_locks osc
10582                 stime=`date +%s`
10583                 time ls -l $DIR/$tdir | wc -l
10584                 etime=`date +%s`
10585                 delta_sa=$((etime - stime))
10586                 log "ls $i files with statahead: $delta_sa sec"
10587                 lctl get_param -n llite.*.statahead_stats
10588                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10589
10590                 [[ $swrong -lt $ewrong ]] &&
10591                         log "statahead was stopped, maybe too many locks held!"
10592                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10593
10594                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10595                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10596                     lctl set_param -n llite.*.statahead_max 0
10597                     lctl get_param llite.*.statahead_max
10598                     cancel_lru_locks mdc
10599                     cancel_lru_locks osc
10600                     stime=`date +%s`
10601                     time ls -l $DIR/$tdir | wc -l
10602                     etime=`date +%s`
10603                     delta=$((etime - stime))
10604                     log "ls $i files again without statahead: $delta sec"
10605                     lctl set_param llite.*.statahead_max=$max
10606                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10607                         if [  $SLOWOK -eq 0 ]; then
10608                                 error "ls $i files is slower with statahead!"
10609                         else
10610                                 log "ls $i files is slower with statahead!"
10611                         fi
10612                         break
10613                     fi
10614                 fi
10615
10616                 [ $delta -gt 20 ] && break
10617                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10618                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10619         done
10620         log "ls done"
10621
10622         stime=`date +%s`
10623         rm -r $DIR/$tdir
10624         sync
10625         etime=`date +%s`
10626         delta=$((etime - stime))
10627         log "rm -r $DIR/$tdir/: $delta seconds"
10628         log "rm done"
10629         lctl get_param -n llite.*.statahead_stats
10630 }
10631 run_test 123a "verify statahead work"
10632
10633 test_123b () { # statahead(bug 15027)
10634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10635
10636         test_mkdir $DIR/$tdir
10637         createmany -o $DIR/$tdir/$tfile-%d 1000
10638
10639         cancel_lru_locks mdc
10640         cancel_lru_locks osc
10641
10642 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10643         lctl set_param fail_loc=0x80000803
10644         ls -lR $DIR/$tdir > /dev/null
10645         log "ls done"
10646         lctl set_param fail_loc=0x0
10647         lctl get_param -n llite.*.statahead_stats
10648         rm -r $DIR/$tdir
10649         sync
10650
10651 }
10652 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10653
10654 test_124a() {
10655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10656         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10657                 skip_env "no lru resize on server"
10658
10659         local NR=2000
10660
10661         test_mkdir $DIR/$tdir
10662
10663         log "create $NR files at $DIR/$tdir"
10664         createmany -o $DIR/$tdir/f $NR ||
10665                 error "failed to create $NR files in $DIR/$tdir"
10666
10667         cancel_lru_locks mdc
10668         ls -l $DIR/$tdir > /dev/null
10669
10670         local NSDIR=""
10671         local LRU_SIZE=0
10672         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10673                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10674                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10675                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10676                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10677                         log "NSDIR=$NSDIR"
10678                         log "NS=$(basename $NSDIR)"
10679                         break
10680                 fi
10681         done
10682
10683         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10684                 skip "Not enough cached locks created!"
10685         fi
10686         log "LRU=$LRU_SIZE"
10687
10688         local SLEEP=30
10689
10690         # We know that lru resize allows one client to hold $LIMIT locks
10691         # for 10h. After that locks begin to be killed by client.
10692         local MAX_HRS=10
10693         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10694         log "LIMIT=$LIMIT"
10695         if [ $LIMIT -lt $LRU_SIZE ]; then
10696                 skip "Limit is too small $LIMIT"
10697         fi
10698
10699         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10700         # killing locks. Some time was spent for creating locks. This means
10701         # that up to the moment of sleep finish we must have killed some of
10702         # them (10-100 locks). This depends on how fast ther were created.
10703         # Many of them were touched in almost the same moment and thus will
10704         # be killed in groups.
10705         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10706
10707         # Use $LRU_SIZE_B here to take into account real number of locks
10708         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10709         local LRU_SIZE_B=$LRU_SIZE
10710         log "LVF=$LVF"
10711         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10712         log "OLD_LVF=$OLD_LVF"
10713         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10714
10715         # Let's make sure that we really have some margin. Client checks
10716         # cached locks every 10 sec.
10717         SLEEP=$((SLEEP+20))
10718         log "Sleep ${SLEEP} sec"
10719         local SEC=0
10720         while ((SEC<$SLEEP)); do
10721                 echo -n "..."
10722                 sleep 5
10723                 SEC=$((SEC+5))
10724                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10725                 echo -n "$LRU_SIZE"
10726         done
10727         echo ""
10728         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10729         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10730
10731         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10732                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10733                 unlinkmany $DIR/$tdir/f $NR
10734                 return
10735         }
10736
10737         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10738         log "unlink $NR files at $DIR/$tdir"
10739         unlinkmany $DIR/$tdir/f $NR
10740 }
10741 run_test 124a "lru resize ======================================="
10742
10743 get_max_pool_limit()
10744 {
10745         local limit=$($LCTL get_param \
10746                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10747         local max=0
10748         for l in $limit; do
10749                 if [[ $l -gt $max ]]; then
10750                         max=$l
10751                 fi
10752         done
10753         echo $max
10754 }
10755
10756 test_124b() {
10757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10758         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10759                 skip_env "no lru resize on server"
10760
10761         LIMIT=$(get_max_pool_limit)
10762
10763         NR=$(($(default_lru_size)*20))
10764         if [[ $NR -gt $LIMIT ]]; then
10765                 log "Limit lock number by $LIMIT locks"
10766                 NR=$LIMIT
10767         fi
10768
10769         IFree=$(mdsrate_inodes_available)
10770         if [ $IFree -lt $NR ]; then
10771                 log "Limit lock number by $IFree inodes"
10772                 NR=$IFree
10773         fi
10774
10775         lru_resize_disable mdc
10776         test_mkdir -p $DIR/$tdir/disable_lru_resize
10777
10778         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10779         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10780         cancel_lru_locks mdc
10781         stime=`date +%s`
10782         PID=""
10783         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10784         PID="$PID $!"
10785         sleep 2
10786         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10787         PID="$PID $!"
10788         sleep 2
10789         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10790         PID="$PID $!"
10791         wait $PID
10792         etime=`date +%s`
10793         nolruresize_delta=$((etime-stime))
10794         log "ls -la time: $nolruresize_delta seconds"
10795         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10796         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10797
10798         lru_resize_enable mdc
10799         test_mkdir -p $DIR/$tdir/enable_lru_resize
10800
10801         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10802         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10803         cancel_lru_locks mdc
10804         stime=`date +%s`
10805         PID=""
10806         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10807         PID="$PID $!"
10808         sleep 2
10809         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10810         PID="$PID $!"
10811         sleep 2
10812         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10813         PID="$PID $!"
10814         wait $PID
10815         etime=`date +%s`
10816         lruresize_delta=$((etime-stime))
10817         log "ls -la time: $lruresize_delta seconds"
10818         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10819
10820         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10821                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10822         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10823                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10824         else
10825                 log "lru resize performs the same with no lru resize"
10826         fi
10827         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10828 }
10829 run_test 124b "lru resize (performance test) ======================="
10830
10831 test_124c() {
10832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10833         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10834                 skip_env "no lru resize on server"
10835
10836         # cache ununsed locks on client
10837         local nr=100
10838         cancel_lru_locks mdc
10839         test_mkdir $DIR/$tdir
10840         createmany -o $DIR/$tdir/f $nr ||
10841                 error "failed to create $nr files in $DIR/$tdir"
10842         ls -l $DIR/$tdir > /dev/null
10843
10844         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10845         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10846         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10847         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10848         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10849
10850         # set lru_max_age to 1 sec
10851         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10852         echo "sleep $((recalc_p * 2)) seconds..."
10853         sleep $((recalc_p * 2))
10854
10855         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10856         # restore lru_max_age
10857         $LCTL set_param -n $nsdir.lru_max_age $max_age
10858         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10859         unlinkmany $DIR/$tdir/f $nr
10860 }
10861 run_test 124c "LRUR cancel very aged locks"
10862
10863 test_124d() {
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10866                 skip_env "no lru resize on server"
10867
10868         # cache ununsed locks on client
10869         local nr=100
10870
10871         lru_resize_disable mdc
10872         stack_trap "lru_resize_enable mdc" EXIT
10873
10874         cancel_lru_locks mdc
10875
10876         # asynchronous object destroy at MDT could cause bl ast to client
10877         test_mkdir $DIR/$tdir
10878         createmany -o $DIR/$tdir/f $nr ||
10879                 error "failed to create $nr files in $DIR/$tdir"
10880         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
10881
10882         ls -l $DIR/$tdir > /dev/null
10883
10884         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10885         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10886         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10887         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10888
10889         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10890
10891         # set lru_max_age to 1 sec
10892         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10893         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
10894
10895         echo "sleep $((recalc_p * 2)) seconds..."
10896         sleep $((recalc_p * 2))
10897
10898         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10899
10900         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10901 }
10902 run_test 124d "cancel very aged locks if lru-resize diasbaled"
10903
10904 test_125() { # 13358
10905         $LCTL get_param -n llite.*.client_type | grep -q local ||
10906                 skip "must run as local client"
10907         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10908                 skip_env "must have acl enabled"
10909         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10910
10911         test_mkdir $DIR/$tdir
10912         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10913         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10914         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10915 }
10916 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10917
10918 test_126() { # bug 12829/13455
10919         $GSS && skip_env "must run as gss disabled"
10920         $LCTL get_param -n llite.*.client_type | grep -q local ||
10921                 skip "must run as local client"
10922         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10923
10924         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10925         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10926         rm -f $DIR/$tfile
10927         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10928 }
10929 run_test 126 "check that the fsgid provided by the client is taken into account"
10930
10931 test_127a() { # bug 15521
10932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10933
10934         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10935         $LCTL set_param osc.*.stats=0
10936         FSIZE=$((2048 * 1024))
10937         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10938         cancel_lru_locks osc
10939         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10940
10941         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10942         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10943                 echo "got $COUNT $NAME"
10944                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10945                 eval $NAME=$COUNT || error "Wrong proc format"
10946
10947                 case $NAME in
10948                         read_bytes|write_bytes)
10949                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10950                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10951                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10952                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10953                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10954                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10955                                 error "sumsquare is too small: $SUMSQ"
10956                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10957                                 error "sumsquare is too big: $SUMSQ"
10958                         ;;
10959                         *) ;;
10960                 esac
10961         done < $DIR/${tfile}.tmp
10962
10963         #check that we actually got some stats
10964         [ "$read_bytes" ] || error "Missing read_bytes stats"
10965         [ "$write_bytes" ] || error "Missing write_bytes stats"
10966         [ "$read_bytes" != 0 ] || error "no read done"
10967         [ "$write_bytes" != 0 ] || error "no write done"
10968 }
10969 run_test 127a "verify the client stats are sane"
10970
10971 test_127b() { # bug LU-333
10972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10973         local name count samp unit min max sum sumsq
10974
10975         $LCTL set_param llite.*.stats=0
10976
10977         # perform 2 reads and writes so MAX is different from SUM.
10978         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10979         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10980         cancel_lru_locks osc
10981         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10982         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10983
10984         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10985         while read name count samp unit min max sum sumsq; do
10986                 echo "got $count $name"
10987                 eval $name=$count || error "Wrong proc format"
10988
10989                 case $name in
10990                 read_bytes)
10991                         [ $count -ne 2 ] && error "count is not 2: $count"
10992                         [ $min -ne $PAGE_SIZE ] &&
10993                                 error "min is not $PAGE_SIZE: $min"
10994                         [ $max -ne $PAGE_SIZE ] &&
10995                                 error "max is incorrect: $max"
10996                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10997                                 error "sum is wrong: $sum"
10998                         ;;
10999                 write_bytes)
11000                         [ $count -ne 2 ] && error "count is not 2: $count"
11001                         [ $min -ne $PAGE_SIZE ] &&
11002                                 error "min is not $PAGE_SIZE: $min"
11003                         [ $max -ne $PAGE_SIZE ] &&
11004                                 error "max is incorrect: $max"
11005                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11006                                 error "sum is wrong: $sum"
11007                         ;;
11008                 *) ;;
11009                 esac
11010         done < $TMP/$tfile.tmp
11011
11012         #check that we actually got some stats
11013         [ "$read_bytes" ] || error "Missing read_bytes stats"
11014         [ "$write_bytes" ] || error "Missing write_bytes stats"
11015         [ "$read_bytes" != 0 ] || error "no read done"
11016         [ "$write_bytes" != 0 ] || error "no write done"
11017
11018         rm -f $TMP/${tfile}.tmp
11019 }
11020 run_test 127b "verify the llite client stats are sane"
11021
11022 test_128() { # bug 15212
11023         touch $DIR/$tfile
11024         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11025                 find $DIR/$tfile
11026                 find $DIR/$tfile
11027         EOF
11028
11029         result=$(grep error $TMP/$tfile.log)
11030         rm -f $DIR/$tfile $TMP/$tfile.log
11031         [ -z "$result" ] ||
11032                 error "consecutive find's under interactive lfs failed"
11033 }
11034 run_test 128 "interactive lfs for 2 consecutive find's"
11035
11036 set_dir_limits () {
11037         local mntdev
11038         local canondev
11039         local node
11040
11041         local ldproc=/proc/fs/ldiskfs
11042         local facets=$(get_facets MDS)
11043
11044         for facet in ${facets//,/ }; do
11045                 canondev=$(ldiskfs_canon \
11046                            *.$(convert_facet2label $facet).mntdev $facet)
11047                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11048                         ldproc=/sys/fs/ldiskfs
11049                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11050                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11051         done
11052 }
11053
11054 check_mds_dmesg() {
11055         local facets=$(get_facets MDS)
11056         for facet in ${facets//,/ }; do
11057                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11058         done
11059         return 1
11060 }
11061
11062 test_129() {
11063         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11064         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11065                 skip "Need MDS version with at least 2.5.56"
11066         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11067                 skip_env "ldiskfs only test"
11068         fi
11069         remote_mds_nodsh && skip "remote MDS with nodsh"
11070
11071         local ENOSPC=28
11072         local EFBIG=27
11073         local has_warning=false
11074
11075         rm -rf $DIR/$tdir
11076         mkdir -p $DIR/$tdir
11077
11078         # block size of mds1
11079         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11080         set_dir_limits $maxsize $maxsize
11081         local dirsize=$(stat -c%s "$DIR/$tdir")
11082         local nfiles=0
11083         while [[ $dirsize -le $maxsize ]]; do
11084                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11085                 rc=$?
11086                 if ! $has_warning; then
11087                         check_mds_dmesg '"is approaching"' && has_warning=true
11088                 fi
11089                 # check two errors:
11090                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11091                 # EFBIG for previous versions included in ldiskfs series
11092                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11093                         set_dir_limits 0 0
11094                         echo "return code $rc received as expected"
11095
11096                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11097                                 error_exit "create failed w/o dir size limit"
11098
11099                         check_mds_dmesg '"has reached"' ||
11100                                 error_exit "reached message should be output"
11101
11102                         [ $has_warning = "false" ] &&
11103                                 error_exit "warning message should be output"
11104
11105                         dirsize=$(stat -c%s "$DIR/$tdir")
11106
11107                         [[ $dirsize -ge $maxsize ]] && return 0
11108                         error_exit "current dir size $dirsize, " \
11109                                    "previous limit $maxsize"
11110                 elif [ $rc -ne 0 ]; then
11111                         set_dir_limits 0 0
11112                         error_exit "return $rc received instead of expected " \
11113                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11114                 fi
11115                 nfiles=$((nfiles + 1))
11116                 dirsize=$(stat -c%s "$DIR/$tdir")
11117         done
11118
11119         set_dir_limits 0 0
11120         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11121 }
11122 run_test 129 "test directory size limit ========================"
11123
11124 OLDIFS="$IFS"
11125 cleanup_130() {
11126         trap 0
11127         IFS="$OLDIFS"
11128 }
11129
11130 test_130a() {
11131         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11132         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11133
11134         trap cleanup_130 EXIT RETURN
11135
11136         local fm_file=$DIR/$tfile
11137         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11138         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11139                 error "dd failed for $fm_file"
11140
11141         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11142         filefrag -ves $fm_file
11143         RC=$?
11144         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11145                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11146         [ $RC != 0 ] && error "filefrag $fm_file failed"
11147
11148         filefrag_op=$(filefrag -ve -k $fm_file |
11149                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11150         lun=$($LFS getstripe -i $fm_file)
11151
11152         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11153         IFS=$'\n'
11154         tot_len=0
11155         for line in $filefrag_op
11156         do
11157                 frag_lun=`echo $line | cut -d: -f5`
11158                 ext_len=`echo $line | cut -d: -f4`
11159                 if (( $frag_lun != $lun )); then
11160                         cleanup_130
11161                         error "FIEMAP on 1-stripe file($fm_file) failed"
11162                         return
11163                 fi
11164                 (( tot_len += ext_len ))
11165         done
11166
11167         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11168                 cleanup_130
11169                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11170                 return
11171         fi
11172
11173         cleanup_130
11174
11175         echo "FIEMAP on single striped file succeeded"
11176 }
11177 run_test 130a "FIEMAP (1-stripe file)"
11178
11179 test_130b() {
11180         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11181
11182         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11183         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11184
11185         trap cleanup_130 EXIT RETURN
11186
11187         local fm_file=$DIR/$tfile
11188         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11189                         error "setstripe on $fm_file"
11190         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11191                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11192
11193         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11194                 error "dd failed on $fm_file"
11195
11196         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11197         filefrag_op=$(filefrag -ve -k $fm_file |
11198                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11199
11200         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11201                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11202
11203         IFS=$'\n'
11204         tot_len=0
11205         num_luns=1
11206         for line in $filefrag_op
11207         do
11208                 frag_lun=$(echo $line | cut -d: -f5 |
11209                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11210                 ext_len=$(echo $line | cut -d: -f4)
11211                 if (( $frag_lun != $last_lun )); then
11212                         if (( tot_len != 1024 )); then
11213                                 cleanup_130
11214                                 error "FIEMAP on $fm_file failed; returned " \
11215                                 "len $tot_len for OST $last_lun instead of 1024"
11216                                 return
11217                         else
11218                                 (( num_luns += 1 ))
11219                                 tot_len=0
11220                         fi
11221                 fi
11222                 (( tot_len += ext_len ))
11223                 last_lun=$frag_lun
11224         done
11225         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11226                 cleanup_130
11227                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11228                         "luns or wrong len for OST $last_lun"
11229                 return
11230         fi
11231
11232         cleanup_130
11233
11234         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11235 }
11236 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11237
11238 test_130c() {
11239         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11240
11241         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11242         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11243
11244         trap cleanup_130 EXIT RETURN
11245
11246         local fm_file=$DIR/$tfile
11247         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11248         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11249                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11250
11251         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11252                         error "dd failed on $fm_file"
11253
11254         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11255         filefrag_op=$(filefrag -ve -k $fm_file |
11256                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11257
11258         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11259                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11260
11261         IFS=$'\n'
11262         tot_len=0
11263         num_luns=1
11264         for line in $filefrag_op
11265         do
11266                 frag_lun=$(echo $line | cut -d: -f5 |
11267                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11268                 ext_len=$(echo $line | cut -d: -f4)
11269                 if (( $frag_lun != $last_lun )); then
11270                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11271                         if (( logical != 512 )); then
11272                                 cleanup_130
11273                                 error "FIEMAP on $fm_file failed; returned " \
11274                                 "logical start for lun $logical instead of 512"
11275                                 return
11276                         fi
11277                         if (( tot_len != 512 )); then
11278                                 cleanup_130
11279                                 error "FIEMAP on $fm_file failed; returned " \
11280                                 "len $tot_len for OST $last_lun instead of 1024"
11281                                 return
11282                         else
11283                                 (( num_luns += 1 ))
11284                                 tot_len=0
11285                         fi
11286                 fi
11287                 (( tot_len += ext_len ))
11288                 last_lun=$frag_lun
11289         done
11290         if (( num_luns != 2 || tot_len != 512 )); then
11291                 cleanup_130
11292                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11293                         "luns or wrong len for OST $last_lun"
11294                 return
11295         fi
11296
11297         cleanup_130
11298
11299         echo "FIEMAP on 2-stripe file with hole succeeded"
11300 }
11301 run_test 130c "FIEMAP (2-stripe file with hole)"
11302
11303 test_130d() {
11304         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11305
11306         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11307         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11308
11309         trap cleanup_130 EXIT RETURN
11310
11311         local fm_file=$DIR/$tfile
11312         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11313                         error "setstripe on $fm_file"
11314         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11315                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11316
11317         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11318         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11319                 error "dd failed on $fm_file"
11320
11321         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11322         filefrag_op=$(filefrag -ve -k $fm_file |
11323                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11324
11325         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11326                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11327
11328         IFS=$'\n'
11329         tot_len=0
11330         num_luns=1
11331         for line in $filefrag_op
11332         do
11333                 frag_lun=$(echo $line | cut -d: -f5 |
11334                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11335                 ext_len=$(echo $line | cut -d: -f4)
11336                 if (( $frag_lun != $last_lun )); then
11337                         if (( tot_len != 1024 )); then
11338                                 cleanup_130
11339                                 error "FIEMAP on $fm_file failed; returned " \
11340                                 "len $tot_len for OST $last_lun instead of 1024"
11341                                 return
11342                         else
11343                                 (( num_luns += 1 ))
11344                                 tot_len=0
11345                         fi
11346                 fi
11347                 (( tot_len += ext_len ))
11348                 last_lun=$frag_lun
11349         done
11350         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11351                 cleanup_130
11352                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11353                         "luns or wrong len for OST $last_lun"
11354                 return
11355         fi
11356
11357         cleanup_130
11358
11359         echo "FIEMAP on N-stripe file succeeded"
11360 }
11361 run_test 130d "FIEMAP (N-stripe file)"
11362
11363 test_130e() {
11364         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11365
11366         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11367         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11368
11369         trap cleanup_130 EXIT RETURN
11370
11371         local fm_file=$DIR/$tfile
11372         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11373         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11374                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11375
11376         NUM_BLKS=512
11377         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11378         for ((i = 0; i < $NUM_BLKS; i++))
11379         do
11380                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11381         done
11382
11383         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11384         filefrag_op=$(filefrag -ve -k $fm_file |
11385                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11386
11387         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11388                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11389
11390         IFS=$'\n'
11391         tot_len=0
11392         num_luns=1
11393         for line in $filefrag_op
11394         do
11395                 frag_lun=$(echo $line | cut -d: -f5 |
11396                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11397                 ext_len=$(echo $line | cut -d: -f4)
11398                 if (( $frag_lun != $last_lun )); then
11399                         if (( tot_len != $EXPECTED_LEN )); then
11400                                 cleanup_130
11401                                 error "FIEMAP on $fm_file failed; returned " \
11402                                 "len $tot_len for OST $last_lun instead " \
11403                                 "of $EXPECTED_LEN"
11404                                 return
11405                         else
11406                                 (( num_luns += 1 ))
11407                                 tot_len=0
11408                         fi
11409                 fi
11410                 (( tot_len += ext_len ))
11411                 last_lun=$frag_lun
11412         done
11413         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11414                 cleanup_130
11415                 error "FIEMAP on $fm_file failed; returned wrong number " \
11416                         "of luns or wrong len for OST $last_lun"
11417                 return
11418         fi
11419
11420         cleanup_130
11421
11422         echo "FIEMAP with continuation calls succeeded"
11423 }
11424 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11425
11426 test_130f() {
11427         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11428         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11429
11430         local fm_file=$DIR/$tfile
11431         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11432                 error "multiop create with lov_delay_create on $fm_file"
11433
11434         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11435         filefrag_extents=$(filefrag -vek $fm_file |
11436                            awk '/extents? found/ { print $2 }')
11437         if [[ "$filefrag_extents" != "0" ]]; then
11438                 error "FIEMAP on $fm_file failed; " \
11439                       "returned $filefrag_extents expected 0"
11440         fi
11441
11442         rm -f $fm_file
11443 }
11444 run_test 130f "FIEMAP (unstriped file)"
11445
11446 # Test for writev/readv
11447 test_131a() {
11448         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11449                 error "writev test failed"
11450         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11451                 error "readv failed"
11452         rm -f $DIR/$tfile
11453 }
11454 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11455
11456 test_131b() {
11457         local fsize=$((524288 + 1048576 + 1572864))
11458         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11459                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11460                         error "append writev test failed"
11461
11462         ((fsize += 1572864 + 1048576))
11463         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11464                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11465                         error "append writev test failed"
11466         rm -f $DIR/$tfile
11467 }
11468 run_test 131b "test append writev"
11469
11470 test_131c() {
11471         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11472         error "NOT PASS"
11473 }
11474 run_test 131c "test read/write on file w/o objects"
11475
11476 test_131d() {
11477         rwv -f $DIR/$tfile -w -n 1 1572864
11478         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11479         if [ "$NOB" != 1572864 ]; then
11480                 error "Short read filed: read $NOB bytes instead of 1572864"
11481         fi
11482         rm -f $DIR/$tfile
11483 }
11484 run_test 131d "test short read"
11485
11486 test_131e() {
11487         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11488         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11489         error "read hitting hole failed"
11490         rm -f $DIR/$tfile
11491 }
11492 run_test 131e "test read hitting hole"
11493
11494 check_stats() {
11495         local facet=$1
11496         local op=$2
11497         local want=${3:-0}
11498         local res
11499
11500         case $facet in
11501         mds*) res=$(do_facet $facet \
11502                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11503                  ;;
11504         ost*) res=$(do_facet $facet \
11505                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11506                  ;;
11507         *) error "Wrong facet '$facet'" ;;
11508         esac
11509         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11510         # if the argument $3 is zero, it means any stat increment is ok.
11511         if [[ $want -gt 0 ]]; then
11512                 local count=$(echo $res | awk '{ print $2 }')
11513                 [[ $count -ne $want ]] &&
11514                         error "The $op counter on $facet is $count, not $want"
11515         fi
11516 }
11517
11518 test_133a() {
11519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11520         remote_ost_nodsh && skip "remote OST with nodsh"
11521         remote_mds_nodsh && skip "remote MDS with nodsh"
11522         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11523                 skip_env "MDS doesn't support rename stats"
11524
11525         local testdir=$DIR/${tdir}/stats_testdir
11526
11527         mkdir -p $DIR/${tdir}
11528
11529         # clear stats.
11530         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11531         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11532
11533         # verify mdt stats first.
11534         mkdir ${testdir} || error "mkdir failed"
11535         check_stats $SINGLEMDS "mkdir" 1
11536         touch ${testdir}/${tfile} || error "touch failed"
11537         check_stats $SINGLEMDS "open" 1
11538         check_stats $SINGLEMDS "close" 1
11539         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11540                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11541                 check_stats $SINGLEMDS "mknod" 2
11542         }
11543         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11544         check_stats $SINGLEMDS "unlink" 1
11545         rm -f ${testdir}/${tfile} || error "file remove failed"
11546         check_stats $SINGLEMDS "unlink" 2
11547
11548         # remove working dir and check mdt stats again.
11549         rmdir ${testdir} || error "rmdir failed"
11550         check_stats $SINGLEMDS "rmdir" 1
11551
11552         local testdir1=$DIR/${tdir}/stats_testdir1
11553         mkdir -p ${testdir}
11554         mkdir -p ${testdir1}
11555         touch ${testdir1}/test1
11556         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11557         check_stats $SINGLEMDS "crossdir_rename" 1
11558
11559         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11560         check_stats $SINGLEMDS "samedir_rename" 1
11561
11562         rm -rf $DIR/${tdir}
11563 }
11564 run_test 133a "Verifying MDT stats ========================================"
11565
11566 test_133b() {
11567         local res
11568
11569         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11570         remote_ost_nodsh && skip "remote OST with nodsh"
11571         remote_mds_nodsh && skip "remote MDS with nodsh"
11572
11573         local testdir=$DIR/${tdir}/stats_testdir
11574
11575         mkdir -p ${testdir} || error "mkdir failed"
11576         touch ${testdir}/${tfile} || error "touch failed"
11577         cancel_lru_locks mdc
11578
11579         # clear stats.
11580         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11581         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11582
11583         # extra mdt stats verification.
11584         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11585         check_stats $SINGLEMDS "setattr" 1
11586         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11587         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11588         then            # LU-1740
11589                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11590                 check_stats $SINGLEMDS "getattr" 1
11591         fi
11592         rm -rf $DIR/${tdir}
11593
11594         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11595         # so the check below is not reliable
11596         [ $MDSCOUNT -eq 1 ] || return 0
11597
11598         # Sleep to avoid a cached response.
11599         #define OBD_STATFS_CACHE_SECONDS 1
11600         sleep 2
11601         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11602         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11603         $LFS df || error "lfs failed"
11604         check_stats $SINGLEMDS "statfs" 1
11605
11606         # check aggregated statfs (LU-10018)
11607         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11608                 return 0
11609         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11610                 return 0
11611         sleep 2
11612         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11613         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11614         df $DIR
11615         check_stats $SINGLEMDS "statfs" 1
11616
11617         # We want to check that the client didn't send OST_STATFS to
11618         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11619         # extra care is needed here.
11620         if remote_mds; then
11621                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11622                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11623
11624                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11625                 [ "$res" ] && error "OST got STATFS"
11626         fi
11627
11628         return 0
11629 }
11630 run_test 133b "Verifying extra MDT stats =================================="
11631
11632 test_133c() {
11633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11634         remote_ost_nodsh && skip "remote OST with nodsh"
11635         remote_mds_nodsh && skip "remote MDS with nodsh"
11636
11637         local testdir=$DIR/$tdir/stats_testdir
11638
11639         test_mkdir -p $testdir
11640
11641         # verify obdfilter stats.
11642         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11643         sync
11644         cancel_lru_locks osc
11645         wait_delete_completed
11646
11647         # clear stats.
11648         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11649         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11650
11651         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11652                 error "dd failed"
11653         sync
11654         cancel_lru_locks osc
11655         check_stats ost1 "write" 1
11656
11657         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11658         check_stats ost1 "read" 1
11659
11660         > $testdir/$tfile || error "truncate failed"
11661         check_stats ost1 "punch" 1
11662
11663         rm -f $testdir/$tfile || error "file remove failed"
11664         wait_delete_completed
11665         check_stats ost1 "destroy" 1
11666
11667         rm -rf $DIR/$tdir
11668 }
11669 run_test 133c "Verifying OST stats ========================================"
11670
11671 order_2() {
11672         local value=$1
11673         local orig=$value
11674         local order=1
11675
11676         while [ $value -ge 2 ]; do
11677                 order=$((order*2))
11678                 value=$((value/2))
11679         done
11680
11681         if [ $orig -gt $order ]; then
11682                 order=$((order*2))
11683         fi
11684         echo $order
11685 }
11686
11687 size_in_KMGT() {
11688     local value=$1
11689     local size=('K' 'M' 'G' 'T');
11690     local i=0
11691     local size_string=$value
11692
11693     while [ $value -ge 1024 ]; do
11694         if [ $i -gt 3 ]; then
11695             #T is the biggest unit we get here, if that is bigger,
11696             #just return XXXT
11697             size_string=${value}T
11698             break
11699         fi
11700         value=$((value >> 10))
11701         if [ $value -lt 1024 ]; then
11702             size_string=${value}${size[$i]}
11703             break
11704         fi
11705         i=$((i + 1))
11706     done
11707
11708     echo $size_string
11709 }
11710
11711 get_rename_size() {
11712         local size=$1
11713         local context=${2:-.}
11714         local sample=$(do_facet $SINGLEMDS $LCTL \
11715                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11716                 grep -A1 $context |
11717                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11718         echo $sample
11719 }
11720
11721 test_133d() {
11722         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11723         remote_ost_nodsh && skip "remote OST with nodsh"
11724         remote_mds_nodsh && skip "remote MDS with nodsh"
11725         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11726                 skip_env "MDS doesn't support rename stats"
11727
11728         local testdir1=$DIR/${tdir}/stats_testdir1
11729         local testdir2=$DIR/${tdir}/stats_testdir2
11730         mkdir -p $DIR/${tdir}
11731
11732         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11733
11734         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11735         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11736
11737         createmany -o $testdir1/test 512 || error "createmany failed"
11738
11739         # check samedir rename size
11740         mv ${testdir1}/test0 ${testdir1}/test_0
11741
11742         local testdir1_size=$(ls -l $DIR/${tdir} |
11743                 awk '/stats_testdir1/ {print $5}')
11744         local testdir2_size=$(ls -l $DIR/${tdir} |
11745                 awk '/stats_testdir2/ {print $5}')
11746
11747         testdir1_size=$(order_2 $testdir1_size)
11748         testdir2_size=$(order_2 $testdir2_size)
11749
11750         testdir1_size=$(size_in_KMGT $testdir1_size)
11751         testdir2_size=$(size_in_KMGT $testdir2_size)
11752
11753         echo "source rename dir size: ${testdir1_size}"
11754         echo "target rename dir size: ${testdir2_size}"
11755
11756         local cmd="do_facet $SINGLEMDS $LCTL "
11757         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11758
11759         eval $cmd || error "$cmd failed"
11760         local samedir=$($cmd | grep 'same_dir')
11761         local same_sample=$(get_rename_size $testdir1_size)
11762         [ -z "$samedir" ] && error "samedir_rename_size count error"
11763         [[ $same_sample -eq 1 ]] ||
11764                 error "samedir_rename_size error $same_sample"
11765         echo "Check same dir rename stats success"
11766
11767         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11768
11769         # check crossdir rename size
11770         mv ${testdir1}/test_0 ${testdir2}/test_0
11771
11772         testdir1_size=$(ls -l $DIR/${tdir} |
11773                 awk '/stats_testdir1/ {print $5}')
11774         testdir2_size=$(ls -l $DIR/${tdir} |
11775                 awk '/stats_testdir2/ {print $5}')
11776
11777         testdir1_size=$(order_2 $testdir1_size)
11778         testdir2_size=$(order_2 $testdir2_size)
11779
11780         testdir1_size=$(size_in_KMGT $testdir1_size)
11781         testdir2_size=$(size_in_KMGT $testdir2_size)
11782
11783         echo "source rename dir size: ${testdir1_size}"
11784         echo "target rename dir size: ${testdir2_size}"
11785
11786         eval $cmd || error "$cmd failed"
11787         local crossdir=$($cmd | grep 'crossdir')
11788         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11789         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11790         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11791         [[ $src_sample -eq 1 ]] ||
11792                 error "crossdir_rename_size error $src_sample"
11793         [[ $tgt_sample -eq 1 ]] ||
11794                 error "crossdir_rename_size error $tgt_sample"
11795         echo "Check cross dir rename stats success"
11796         rm -rf $DIR/${tdir}
11797 }
11798 run_test 133d "Verifying rename_stats ========================================"
11799
11800 test_133e() {
11801         remote_mds_nodsh && skip "remote MDS with nodsh"
11802         remote_ost_nodsh && skip "remote OST with nodsh"
11803         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11804
11805         local testdir=$DIR/${tdir}/stats_testdir
11806         local ctr f0 f1 bs=32768 count=42 sum
11807
11808         mkdir -p ${testdir} || error "mkdir failed"
11809
11810         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11811
11812         for ctr in {write,read}_bytes; do
11813                 sync
11814                 cancel_lru_locks osc
11815
11816                 do_facet ost1 $LCTL set_param -n \
11817                         "obdfilter.*.exports.clear=clear"
11818
11819                 if [ $ctr = write_bytes ]; then
11820                         f0=/dev/zero
11821                         f1=${testdir}/${tfile}
11822                 else
11823                         f0=${testdir}/${tfile}
11824                         f1=/dev/null
11825                 fi
11826
11827                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11828                         error "dd failed"
11829                 sync
11830                 cancel_lru_locks osc
11831
11832                 sum=$(do_facet ost1 $LCTL get_param \
11833                         "obdfilter.*.exports.*.stats" |
11834                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11835                                 $1 == ctr { sum += $7 }
11836                                 END { printf("%0.0f", sum) }')
11837
11838                 if ((sum != bs * count)); then
11839                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11840                 fi
11841         done
11842
11843         rm -rf $DIR/${tdir}
11844 }
11845 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11846
11847 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11848
11849 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11850 # not honor the -ignore_readdir_race option correctly. So we call
11851 # error_ignore() rather than error() in these cases. See LU-11152.
11852 error_133() {
11853         if (find --version; do_facet mds1 find --version) |
11854                 grep -q '\b4\.5\.1[1-4]\b'; then
11855                 error_ignore LU-11152 "$@"
11856         else
11857                 error "$@"
11858         fi
11859 }
11860
11861 test_133f() {
11862         # First without trusting modes.
11863         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11864         echo "proc_dirs='$proc_dirs'"
11865         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11866         find $proc_dirs -exec cat '{}' \; &> /dev/null
11867
11868         # Second verifying readability.
11869         $LCTL get_param -R '*' &> /dev/null
11870
11871         # Verifing writability with badarea_io.
11872         find $proc_dirs \
11873                 -ignore_readdir_race \
11874                 -type f \
11875                 -not -name force_lbug \
11876                 -not -name changelog_mask \
11877                 -exec badarea_io '{}' \; ||
11878                         error_133 "find $proc_dirs failed"
11879 }
11880 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11881
11882 test_133g() {
11883         remote_mds_nodsh && skip "remote MDS with nodsh"
11884         remote_ost_nodsh && skip "remote OST with nodsh"
11885
11886         # eventually, this can also be replaced with "lctl get_param -R",
11887         # but not until that option is always available on the server
11888         local facet
11889         for facet in mds1 ost1; do
11890                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11891                         skip_noexit "Too old lustre on $facet"
11892                 local facet_proc_dirs=$(do_facet $facet \
11893                                         \\\ls -d $proc_regexp 2>/dev/null)
11894                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11895                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11896                 do_facet $facet find $facet_proc_dirs \
11897                         ! -name req_history \
11898                         -exec cat '{}' \\\; &> /dev/null
11899
11900                 do_facet $facet find $facet_proc_dirs \
11901                         ! -name req_history \
11902                         -type f \
11903                         -exec cat '{}' \\\; &> /dev/null ||
11904                                 error "proc file read failed"
11905
11906                 do_facet $facet find $facet_proc_dirs \
11907                         -ignore_readdir_race \
11908                         -type f \
11909                         -not -name force_lbug \
11910                         -not -name changelog_mask \
11911                         -exec badarea_io '{}' \\\; ||
11912                                 error_133 "$facet find $facet_proc_dirs failed"
11913         done
11914
11915         # remount the FS in case writes/reads /proc break the FS
11916         cleanup || error "failed to unmount"
11917         setup || error "failed to setup"
11918         true
11919 }
11920 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11921
11922 test_133h() {
11923         remote_mds_nodsh && skip "remote MDS with nodsh"
11924         remote_ost_nodsh && skip "remote OST with nodsh"
11925         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11926                 skip "Need MDS version at least 2.9.54"
11927
11928         local facet
11929
11930         for facet in client mds1 ost1; do
11931                 local facet_proc_dirs=$(do_facet $facet \
11932                                         \\\ls -d $proc_regexp 2> /dev/null)
11933                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11934                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11935                 # Get the list of files that are missing the terminating newline
11936                 local missing=($(do_facet $facet \
11937                         find ${facet_proc_dirs} -type f \|              \
11938                                 while read F\; do                       \
11939                                         awk -v FS='\v' -v RS='\v\v'     \
11940                                         "'END { if(NR>0 &&              \
11941                                         \\\$NF !~ /.*\\\n\$/)           \
11942                                                 print FILENAME}'"       \
11943                                         '\$F'\;                         \
11944                                 done 2>/dev/null))
11945                 [ ${#missing[*]} -eq 0 ] ||
11946                         error "files do not end with newline: ${missing[*]}"
11947         done
11948 }
11949 run_test 133h "Proc files should end with newlines"
11950
11951 test_134a() {
11952         remote_mds_nodsh && skip "remote MDS with nodsh"
11953         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11954                 skip "Need MDS version at least 2.7.54"
11955
11956         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11957         cancel_lru_locks mdc
11958
11959         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11960         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11961         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11962
11963         local nr=1000
11964         createmany -o $DIR/$tdir/f $nr ||
11965                 error "failed to create $nr files in $DIR/$tdir"
11966         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11967
11968         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11969         do_facet mds1 $LCTL set_param fail_loc=0x327
11970         do_facet mds1 $LCTL set_param fail_val=500
11971         touch $DIR/$tdir/m
11972
11973         echo "sleep 10 seconds ..."
11974         sleep 10
11975         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11976
11977         do_facet mds1 $LCTL set_param fail_loc=0
11978         do_facet mds1 $LCTL set_param fail_val=0
11979         [ $lck_cnt -lt $unused ] ||
11980                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11981
11982         rm $DIR/$tdir/m
11983         unlinkmany $DIR/$tdir/f $nr
11984 }
11985 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11986
11987 test_134b() {
11988         remote_mds_nodsh && skip "remote MDS with nodsh"
11989         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11990                 skip "Need MDS version at least 2.7.54"
11991
11992         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11993         cancel_lru_locks mdc
11994
11995         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11996                         ldlm.lock_reclaim_threshold_mb)
11997         # disable reclaim temporarily
11998         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11999
12000         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12001         do_facet mds1 $LCTL set_param fail_loc=0x328
12002         do_facet mds1 $LCTL set_param fail_val=500
12003
12004         $LCTL set_param debug=+trace
12005
12006         local nr=600
12007         createmany -o $DIR/$tdir/f $nr &
12008         local create_pid=$!
12009
12010         echo "Sleep $TIMEOUT seconds ..."
12011         sleep $TIMEOUT
12012         if ! ps -p $create_pid  > /dev/null 2>&1; then
12013                 do_facet mds1 $LCTL set_param fail_loc=0
12014                 do_facet mds1 $LCTL set_param fail_val=0
12015                 do_facet mds1 $LCTL set_param \
12016                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12017                 error "createmany finished incorrectly!"
12018         fi
12019         do_facet mds1 $LCTL set_param fail_loc=0
12020         do_facet mds1 $LCTL set_param fail_val=0
12021         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12022         wait $create_pid || return 1
12023
12024         unlinkmany $DIR/$tdir/f $nr
12025 }
12026 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12027
12028 test_140() { #bug-17379
12029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12030
12031         test_mkdir $DIR/$tdir
12032         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12033         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12034
12035         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12036         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12037         local i=0
12038         while i=$((i + 1)); do
12039                 test_mkdir $i
12040                 cd $i || error "Changing to $i"
12041                 ln -s ../stat stat || error "Creating stat symlink"
12042                 # Read the symlink until ELOOP present,
12043                 # not LBUGing the system is considered success,
12044                 # we didn't overrun the stack.
12045                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12046                 if [ $ret -ne 0 ]; then
12047                         if [ $ret -eq 40 ]; then
12048                                 break  # -ELOOP
12049                         else
12050                                 error "Open stat symlink"
12051                                         return
12052                         fi
12053                 fi
12054         done
12055         i=$((i - 1))
12056         echo "The symlink depth = $i"
12057         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12058                 error "Invalid symlink depth"
12059
12060         # Test recursive symlink
12061         ln -s symlink_self symlink_self
12062         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12063         echo "open symlink_self returns $ret"
12064         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12065 }
12066 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12067
12068 test_150() {
12069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12070
12071         local TF="$TMP/$tfile"
12072
12073         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12074         cp $TF $DIR/$tfile
12075         cancel_lru_locks $OSC
12076         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12077         remount_client $MOUNT
12078         df -P $MOUNT
12079         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12080
12081         $TRUNCATE $TF 6000
12082         $TRUNCATE $DIR/$tfile 6000
12083         cancel_lru_locks $OSC
12084         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12085
12086         echo "12345" >>$TF
12087         echo "12345" >>$DIR/$tfile
12088         cancel_lru_locks $OSC
12089         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12090
12091         echo "12345" >>$TF
12092         echo "12345" >>$DIR/$tfile
12093         cancel_lru_locks $OSC
12094         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12095
12096         rm -f $TF
12097         true
12098 }
12099 run_test 150 "truncate/append tests"
12100
12101 #LU-2902 roc_hit was not able to read all values from lproc
12102 function roc_hit_init() {
12103         local list=$(comma_list $(osts_nodes))
12104         local dir=$DIR/$tdir-check
12105         local file=$dir/$tfile
12106         local BEFORE
12107         local AFTER
12108         local idx
12109
12110         test_mkdir $dir
12111         #use setstripe to do a write to every ost
12112         for i in $(seq 0 $((OSTCOUNT-1))); do
12113                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12114                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12115                 idx=$(printf %04x $i)
12116                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12117                         awk '$1 == "cache_access" {sum += $7}
12118                                 END { printf("%0.0f", sum) }')
12119
12120                 cancel_lru_locks osc
12121                 cat $file >/dev/null
12122
12123                 AFTER=$(get_osd_param $list *OST*$idx stats |
12124                         awk '$1 == "cache_access" {sum += $7}
12125                                 END { printf("%0.0f", sum) }')
12126
12127                 echo BEFORE:$BEFORE AFTER:$AFTER
12128                 if ! let "AFTER - BEFORE == 4"; then
12129                         rm -rf $dir
12130                         error "roc_hit is not safe to use"
12131                 fi
12132                 rm $file
12133         done
12134
12135         rm -rf $dir
12136 }
12137
12138 function roc_hit() {
12139         local list=$(comma_list $(osts_nodes))
12140         echo $(get_osd_param $list '' stats |
12141                 awk '$1 == "cache_hit" {sum += $7}
12142                         END { printf("%0.0f", sum) }')
12143 }
12144
12145 function set_cache() {
12146         local on=1
12147
12148         if [ "$2" == "off" ]; then
12149                 on=0;
12150         fi
12151         local list=$(comma_list $(osts_nodes))
12152         set_osd_param $list '' $1_cache_enable $on
12153
12154         cancel_lru_locks osc
12155 }
12156
12157 test_151() {
12158         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12159         remote_ost_nodsh && skip "remote OST with nodsh"
12160
12161         local CPAGES=3
12162         local list=$(comma_list $(osts_nodes))
12163
12164         # check whether obdfilter is cache capable at all
12165         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12166                 skip "not cache-capable obdfilter"
12167         fi
12168
12169         # check cache is enabled on all obdfilters
12170         if get_osd_param $list '' read_cache_enable | grep 0; then
12171                 skip "oss cache is disabled"
12172         fi
12173
12174         set_osd_param $list '' writethrough_cache_enable 1
12175
12176         # check write cache is enabled on all obdfilters
12177         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12178                 skip "oss write cache is NOT enabled"
12179         fi
12180
12181         roc_hit_init
12182
12183         #define OBD_FAIL_OBD_NO_LRU  0x609
12184         do_nodes $list $LCTL set_param fail_loc=0x609
12185
12186         # pages should be in the case right after write
12187         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12188                 error "dd failed"
12189
12190         local BEFORE=$(roc_hit)
12191         cancel_lru_locks osc
12192         cat $DIR/$tfile >/dev/null
12193         local AFTER=$(roc_hit)
12194
12195         do_nodes $list $LCTL set_param fail_loc=0
12196
12197         if ! let "AFTER - BEFORE == CPAGES"; then
12198                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12199         fi
12200
12201         # the following read invalidates the cache
12202         cancel_lru_locks osc
12203         set_osd_param $list '' read_cache_enable 0
12204         cat $DIR/$tfile >/dev/null
12205
12206         # now data shouldn't be found in the cache
12207         BEFORE=$(roc_hit)
12208         cancel_lru_locks osc
12209         cat $DIR/$tfile >/dev/null
12210         AFTER=$(roc_hit)
12211         if let "AFTER - BEFORE != 0"; then
12212                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12213         fi
12214
12215         set_osd_param $list '' read_cache_enable 1
12216         rm -f $DIR/$tfile
12217 }
12218 run_test 151 "test cache on oss and controls ==============================="
12219
12220 test_152() {
12221         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12222
12223         local TF="$TMP/$tfile"
12224
12225         # simulate ENOMEM during write
12226 #define OBD_FAIL_OST_NOMEM      0x226
12227         lctl set_param fail_loc=0x80000226
12228         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12229         cp $TF $DIR/$tfile
12230         sync || error "sync failed"
12231         lctl set_param fail_loc=0
12232
12233         # discard client's cache
12234         cancel_lru_locks osc
12235
12236         # simulate ENOMEM during read
12237         lctl set_param fail_loc=0x80000226
12238         cmp $TF $DIR/$tfile || error "cmp failed"
12239         lctl set_param fail_loc=0
12240
12241         rm -f $TF
12242 }
12243 run_test 152 "test read/write with enomem ============================"
12244
12245 test_153() {
12246         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12247 }
12248 run_test 153 "test if fdatasync does not crash ======================="
12249
12250 dot_lustre_fid_permission_check() {
12251         local fid=$1
12252         local ffid=$MOUNT/.lustre/fid/$fid
12253         local test_dir=$2
12254
12255         echo "stat fid $fid"
12256         stat $ffid > /dev/null || error "stat $ffid failed."
12257         echo "touch fid $fid"
12258         touch $ffid || error "touch $ffid failed."
12259         echo "write to fid $fid"
12260         cat /etc/hosts > $ffid || error "write $ffid failed."
12261         echo "read fid $fid"
12262         diff /etc/hosts $ffid || error "read $ffid failed."
12263         echo "append write to fid $fid"
12264         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12265         echo "rename fid $fid"
12266         mv $ffid $test_dir/$tfile.1 &&
12267                 error "rename $ffid to $tfile.1 should fail."
12268         touch $test_dir/$tfile.1
12269         mv $test_dir/$tfile.1 $ffid &&
12270                 error "rename $tfile.1 to $ffid should fail."
12271         rm -f $test_dir/$tfile.1
12272         echo "truncate fid $fid"
12273         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12274         echo "link fid $fid"
12275         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12276         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12277                 echo "setfacl fid $fid"
12278                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12279                 echo "getfacl fid $fid"
12280                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12281         fi
12282         echo "unlink fid $fid"
12283         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12284         echo "mknod fid $fid"
12285         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12286
12287         fid=[0xf00000400:0x1:0x0]
12288         ffid=$MOUNT/.lustre/fid/$fid
12289
12290         echo "stat non-exist fid $fid"
12291         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12292         echo "write to non-exist fid $fid"
12293         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12294         echo "link new fid $fid"
12295         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12296
12297         mkdir -p $test_dir/$tdir
12298         touch $test_dir/$tdir/$tfile
12299         fid=$($LFS path2fid $test_dir/$tdir)
12300         rc=$?
12301         [ $rc -ne 0 ] &&
12302                 error "error: could not get fid for $test_dir/$dir/$tfile."
12303
12304         ffid=$MOUNT/.lustre/fid/$fid
12305
12306         echo "ls $fid"
12307         ls $ffid > /dev/null || error "ls $ffid failed."
12308         echo "touch $fid/$tfile.1"
12309         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12310
12311         echo "touch $MOUNT/.lustre/fid/$tfile"
12312         touch $MOUNT/.lustre/fid/$tfile && \
12313                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12314
12315         echo "setxattr to $MOUNT/.lustre/fid"
12316         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12317
12318         echo "listxattr for $MOUNT/.lustre/fid"
12319         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12320
12321         echo "delxattr from $MOUNT/.lustre/fid"
12322         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12323
12324         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12325         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12326                 error "touch invalid fid should fail."
12327
12328         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12329         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12330                 error "touch non-normal fid should fail."
12331
12332         echo "rename $tdir to $MOUNT/.lustre/fid"
12333         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12334                 error "rename to $MOUNT/.lustre/fid should fail."
12335
12336         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12337         then            # LU-3547
12338                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12339                 local new_obf_mode=777
12340
12341                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12342                 chmod $new_obf_mode $DIR/.lustre/fid ||
12343                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12344
12345                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12346                 [ $obf_mode -eq $new_obf_mode ] ||
12347                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12348
12349                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12350                 chmod $old_obf_mode $DIR/.lustre/fid ||
12351                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12352         fi
12353
12354         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12355         fid=$($LFS path2fid $test_dir/$tfile-2)
12356
12357         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12358         then # LU-5424
12359                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12360                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12361                         error "create lov data thru .lustre failed"
12362         fi
12363         echo "cp /etc/passwd $test_dir/$tfile-2"
12364         cp /etc/passwd $test_dir/$tfile-2 ||
12365                 error "copy to $test_dir/$tfile-2 failed."
12366         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12367         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12368                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12369
12370         rm -rf $test_dir/tfile.lnk
12371         rm -rf $test_dir/$tfile-2
12372 }
12373
12374 test_154A() {
12375         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12376                 skip "Need MDS version at least 2.4.1"
12377
12378         local tf=$DIR/$tfile
12379         touch $tf
12380
12381         local fid=$($LFS path2fid $tf)
12382         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12383
12384         # check that we get the same pathname back
12385         local found=$($LFS fid2path $MOUNT "$fid")
12386         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12387         [ "$found" == "$tf" ] ||
12388                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12389 }
12390 run_test 154A "lfs path2fid and fid2path basic checks"
12391
12392 test_154B() {
12393         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12394                 skip "Need MDS version at least 2.4.1"
12395
12396         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12397         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12398         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12399         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12400
12401         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12402         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12403
12404         # check that we get the same pathname
12405         echo "PFID: $PFID, name: $name"
12406         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12407         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12408         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12409                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12410
12411         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12412 }
12413 run_test 154B "verify the ll_decode_linkea tool"
12414
12415 test_154a() {
12416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12417         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12418         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12419                 skip "Need MDS version at least 2.2.51"
12420         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12421
12422         cp /etc/hosts $DIR/$tfile
12423
12424         fid=$($LFS path2fid $DIR/$tfile)
12425         rc=$?
12426         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12427
12428         dot_lustre_fid_permission_check "$fid" $DIR ||
12429                 error "dot lustre permission check $fid failed"
12430
12431         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12432
12433         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12434
12435         touch $MOUNT/.lustre/file &&
12436                 error "creation is not allowed under .lustre"
12437
12438         mkdir $MOUNT/.lustre/dir &&
12439                 error "mkdir is not allowed under .lustre"
12440
12441         rm -rf $DIR/$tfile
12442 }
12443 run_test 154a "Open-by-FID"
12444
12445 test_154b() {
12446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12447         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12448         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12449         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12450                 skip "Need MDS version at least 2.2.51"
12451
12452         local remote_dir=$DIR/$tdir/remote_dir
12453         local MDTIDX=1
12454         local rc=0
12455
12456         mkdir -p $DIR/$tdir
12457         $LFS mkdir -i $MDTIDX $remote_dir ||
12458                 error "create remote directory failed"
12459
12460         cp /etc/hosts $remote_dir/$tfile
12461
12462         fid=$($LFS path2fid $remote_dir/$tfile)
12463         rc=$?
12464         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12465
12466         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12467                 error "dot lustre permission check $fid failed"
12468         rm -rf $DIR/$tdir
12469 }
12470 run_test 154b "Open-by-FID for remote directory"
12471
12472 test_154c() {
12473         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12474                 skip "Need MDS version at least 2.4.1"
12475
12476         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12477         local FID1=$($LFS path2fid $DIR/$tfile.1)
12478         local FID2=$($LFS path2fid $DIR/$tfile.2)
12479         local FID3=$($LFS path2fid $DIR/$tfile.3)
12480
12481         local N=1
12482         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12483                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12484                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12485                 local want=FID$N
12486                 [ "$FID" = "${!want}" ] ||
12487                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12488                 N=$((N + 1))
12489         done
12490
12491         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12492         do
12493                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12494                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12495                 N=$((N + 1))
12496         done
12497 }
12498 run_test 154c "lfs path2fid and fid2path multiple arguments"
12499
12500 test_154d() {
12501         remote_mds_nodsh && skip "remote MDS with nodsh"
12502         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12503                 skip "Need MDS version at least 2.5.53"
12504
12505         if remote_mds; then
12506                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12507         else
12508                 nid="0@lo"
12509         fi
12510         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12511         local fd
12512         local cmd
12513
12514         rm -f $DIR/$tfile
12515         touch $DIR/$tfile
12516
12517         local fid=$($LFS path2fid $DIR/$tfile)
12518         # Open the file
12519         fd=$(free_fd)
12520         cmd="exec $fd<$DIR/$tfile"
12521         eval $cmd
12522         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12523         echo "$fid_list" | grep "$fid"
12524         rc=$?
12525
12526         cmd="exec $fd>/dev/null"
12527         eval $cmd
12528         if [ $rc -ne 0 ]; then
12529                 error "FID $fid not found in open files list $fid_list"
12530         fi
12531 }
12532 run_test 154d "Verify open file fid"
12533
12534 test_154e()
12535 {
12536         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12537                 skip "Need MDS version at least 2.6.50"
12538
12539         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12540                 error ".lustre returned by readdir"
12541         fi
12542 }
12543 run_test 154e ".lustre is not returned by readdir"
12544
12545 test_154f() {
12546         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12547
12548         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12549         test_mkdir -p -c1 $DIR/$tdir/d
12550         # test dirs inherit from its stripe
12551         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12552         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12553         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12554         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12555         touch $DIR/f
12556
12557         # get fid of parents
12558         local FID0=$($LFS path2fid $DIR/$tdir/d)
12559         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12560         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12561         local FID3=$($LFS path2fid $DIR)
12562
12563         # check that path2fid --parents returns expected <parent_fid>/name
12564         # 1) test for a directory (single parent)
12565         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12566         [ "$parent" == "$FID0/foo1" ] ||
12567                 error "expected parent: $FID0/foo1, got: $parent"
12568
12569         # 2) test for a file with nlink > 1 (multiple parents)
12570         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12571         echo "$parent" | grep -F "$FID1/$tfile" ||
12572                 error "$FID1/$tfile not returned in parent list"
12573         echo "$parent" | grep -F "$FID2/link" ||
12574                 error "$FID2/link not returned in parent list"
12575
12576         # 3) get parent by fid
12577         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12578         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12579         echo "$parent" | grep -F "$FID1/$tfile" ||
12580                 error "$FID1/$tfile not returned in parent list (by fid)"
12581         echo "$parent" | grep -F "$FID2/link" ||
12582                 error "$FID2/link not returned in parent list (by fid)"
12583
12584         # 4) test for entry in root directory
12585         parent=$($LFS path2fid --parents $DIR/f)
12586         echo "$parent" | grep -F "$FID3/f" ||
12587                 error "$FID3/f not returned in parent list"
12588
12589         # 5) test it on root directory
12590         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12591                 error "$MOUNT should not have parents"
12592
12593         # enable xattr caching and check that linkea is correctly updated
12594         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12595         save_lustre_params client "llite.*.xattr_cache" > $save
12596         lctl set_param llite.*.xattr_cache 1
12597
12598         # 6.1) linkea update on rename
12599         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12600
12601         # get parents by fid
12602         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12603         # foo1 should no longer be returned in parent list
12604         echo "$parent" | grep -F "$FID1" &&
12605                 error "$FID1 should no longer be in parent list"
12606         # the new path should appear
12607         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12608                 error "$FID2/$tfile.moved is not in parent list"
12609
12610         # 6.2) linkea update on unlink
12611         rm -f $DIR/$tdir/d/foo2/link
12612         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12613         # foo2/link should no longer be returned in parent list
12614         echo "$parent" | grep -F "$FID2/link" &&
12615                 error "$FID2/link should no longer be in parent list"
12616         true
12617
12618         rm -f $DIR/f
12619         restore_lustre_params < $save
12620         rm -f $save
12621 }
12622 run_test 154f "get parent fids by reading link ea"
12623
12624 test_154g()
12625 {
12626         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12627         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12628            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12629                 skip "Need MDS version at least 2.6.92"
12630
12631         mkdir -p $DIR/$tdir
12632         llapi_fid_test -d $DIR/$tdir
12633 }
12634 run_test 154g "various llapi FID tests"
12635
12636 test_155_small_load() {
12637     local temp=$TMP/$tfile
12638     local file=$DIR/$tfile
12639
12640     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12641         error "dd of=$temp bs=6096 count=1 failed"
12642     cp $temp $file
12643     cancel_lru_locks $OSC
12644     cmp $temp $file || error "$temp $file differ"
12645
12646     $TRUNCATE $temp 6000
12647     $TRUNCATE $file 6000
12648     cmp $temp $file || error "$temp $file differ (truncate1)"
12649
12650     echo "12345" >>$temp
12651     echo "12345" >>$file
12652     cmp $temp $file || error "$temp $file differ (append1)"
12653
12654     echo "12345" >>$temp
12655     echo "12345" >>$file
12656     cmp $temp $file || error "$temp $file differ (append2)"
12657
12658     rm -f $temp $file
12659     true
12660 }
12661
12662 test_155_big_load() {
12663         remote_ost_nodsh && skip "remote OST with nodsh"
12664
12665         local temp=$TMP/$tfile
12666         local file=$DIR/$tfile
12667
12668         free_min_max
12669         local cache_size=$(do_facet ost$((MAXI+1)) \
12670                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12671         local large_file_size=$((cache_size * 2))
12672
12673         echo "OSS cache size: $cache_size KB"
12674         echo "Large file size: $large_file_size KB"
12675
12676         [ $MAXV -le $large_file_size ] &&
12677                 skip_env "max available OST size needs > $large_file_size KB"
12678
12679         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12680
12681         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12682                 error "dd of=$temp bs=$large_file_size count=1k failed"
12683         cp $temp $file
12684         ls -lh $temp $file
12685         cancel_lru_locks osc
12686         cmp $temp $file || error "$temp $file differ"
12687
12688         rm -f $temp $file
12689         true
12690 }
12691
12692 save_writethrough() {
12693         local facets=$(get_facets OST)
12694
12695         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12696 }
12697
12698 test_155a() {
12699         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12700
12701         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12702
12703         save_writethrough $p
12704
12705         set_cache read on
12706         set_cache writethrough on
12707         test_155_small_load
12708         restore_lustre_params < $p
12709         rm -f $p
12710 }
12711 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12712
12713 test_155b() {
12714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12715
12716         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12717
12718         save_writethrough $p
12719
12720         set_cache read on
12721         set_cache writethrough off
12722         test_155_small_load
12723         restore_lustre_params < $p
12724         rm -f $p
12725 }
12726 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12727
12728 test_155c() {
12729         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12730
12731         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12732
12733         save_writethrough $p
12734
12735         set_cache read off
12736         set_cache writethrough on
12737         test_155_small_load
12738         restore_lustre_params < $p
12739         rm -f $p
12740 }
12741 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12742
12743 test_155d() {
12744         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12745
12746         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12747
12748         save_writethrough $p
12749
12750         set_cache read off
12751         set_cache writethrough off
12752         test_155_small_load
12753         restore_lustre_params < $p
12754         rm -f $p
12755 }
12756 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12757
12758 test_155e() {
12759         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12760
12761         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12762
12763         save_writethrough $p
12764
12765         set_cache read on
12766         set_cache writethrough on
12767         test_155_big_load
12768         restore_lustre_params < $p
12769         rm -f $p
12770 }
12771 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12772
12773 test_155f() {
12774         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12775
12776         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12777
12778         save_writethrough $p
12779
12780         set_cache read on
12781         set_cache writethrough off
12782         test_155_big_load
12783         restore_lustre_params < $p
12784         rm -f $p
12785 }
12786 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12787
12788 test_155g() {
12789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12790
12791         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12792
12793         save_writethrough $p
12794
12795         set_cache read off
12796         set_cache writethrough on
12797         test_155_big_load
12798         restore_lustre_params < $p
12799         rm -f $p
12800 }
12801 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12802
12803 test_155h() {
12804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12805
12806         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12807
12808         save_writethrough $p
12809
12810         set_cache read off
12811         set_cache writethrough off
12812         test_155_big_load
12813         restore_lustre_params < $p
12814         rm -f $p
12815 }
12816 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12817
12818 test_156() {
12819         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12820         remote_ost_nodsh && skip "remote OST with nodsh"
12821         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12822                 skip "stats not implemented on old servers"
12823         [ "$ost1_FSTYPE" = "zfs" ] &&
12824                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12825
12826         local CPAGES=3
12827         local BEFORE
12828         local AFTER
12829         local file="$DIR/$tfile"
12830         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12831
12832         save_writethrough $p
12833         roc_hit_init
12834
12835         log "Turn on read and write cache"
12836         set_cache read on
12837         set_cache writethrough on
12838
12839         log "Write data and read it back."
12840         log "Read should be satisfied from the cache."
12841         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12842         BEFORE=$(roc_hit)
12843         cancel_lru_locks osc
12844         cat $file >/dev/null
12845         AFTER=$(roc_hit)
12846         if ! let "AFTER - BEFORE == CPAGES"; then
12847                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12848         else
12849                 log "cache hits:: before: $BEFORE, after: $AFTER"
12850         fi
12851
12852         log "Read again; it should be satisfied from the cache."
12853         BEFORE=$AFTER
12854         cancel_lru_locks osc
12855         cat $file >/dev/null
12856         AFTER=$(roc_hit)
12857         if ! let "AFTER - BEFORE == CPAGES"; then
12858                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12859         else
12860                 log "cache hits:: before: $BEFORE, after: $AFTER"
12861         fi
12862
12863         log "Turn off the read cache and turn on the write cache"
12864         set_cache read off
12865         set_cache writethrough on
12866
12867         log "Read again; it should be satisfied from the cache."
12868         BEFORE=$(roc_hit)
12869         cancel_lru_locks osc
12870         cat $file >/dev/null
12871         AFTER=$(roc_hit)
12872         if ! let "AFTER - BEFORE == CPAGES"; then
12873                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12874         else
12875                 log "cache hits:: before: $BEFORE, after: $AFTER"
12876         fi
12877
12878         log "Read again; it should not be satisfied from the cache."
12879         BEFORE=$AFTER
12880         cancel_lru_locks osc
12881         cat $file >/dev/null
12882         AFTER=$(roc_hit)
12883         if ! let "AFTER - BEFORE == 0"; then
12884                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12885         else
12886                 log "cache hits:: before: $BEFORE, after: $AFTER"
12887         fi
12888
12889         log "Write data and read it back."
12890         log "Read should be satisfied from the cache."
12891         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12892         BEFORE=$(roc_hit)
12893         cancel_lru_locks osc
12894         cat $file >/dev/null
12895         AFTER=$(roc_hit)
12896         if ! let "AFTER - BEFORE == CPAGES"; then
12897                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12898         else
12899                 log "cache hits:: before: $BEFORE, after: $AFTER"
12900         fi
12901
12902         log "Read again; it should not be satisfied from the cache."
12903         BEFORE=$AFTER
12904         cancel_lru_locks osc
12905         cat $file >/dev/null
12906         AFTER=$(roc_hit)
12907         if ! let "AFTER - BEFORE == 0"; then
12908                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12909         else
12910                 log "cache hits:: before: $BEFORE, after: $AFTER"
12911         fi
12912
12913         log "Turn off read and write cache"
12914         set_cache read off
12915         set_cache writethrough off
12916
12917         log "Write data and read it back"
12918         log "It should not be satisfied from the cache."
12919         rm -f $file
12920         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12921         cancel_lru_locks osc
12922         BEFORE=$(roc_hit)
12923         cat $file >/dev/null
12924         AFTER=$(roc_hit)
12925         if ! let "AFTER - BEFORE == 0"; then
12926                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12927         else
12928                 log "cache hits:: before: $BEFORE, after: $AFTER"
12929         fi
12930
12931         log "Turn on the read cache and turn off the write cache"
12932         set_cache read on
12933         set_cache writethrough off
12934
12935         log "Write data and read it back"
12936         log "It should not be satisfied from the cache."
12937         rm -f $file
12938         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12939         BEFORE=$(roc_hit)
12940         cancel_lru_locks osc
12941         cat $file >/dev/null
12942         AFTER=$(roc_hit)
12943         if ! let "AFTER - BEFORE == 0"; then
12944                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12945         else
12946                 log "cache hits:: before: $BEFORE, after: $AFTER"
12947         fi
12948
12949         log "Read again; it should be satisfied from the cache."
12950         BEFORE=$(roc_hit)
12951         cancel_lru_locks osc
12952         cat $file >/dev/null
12953         AFTER=$(roc_hit)
12954         if ! let "AFTER - BEFORE == CPAGES"; then
12955                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12956         else
12957                 log "cache hits:: before: $BEFORE, after: $AFTER"
12958         fi
12959
12960         restore_lustre_params < $p
12961         rm -f $p $file
12962 }
12963 run_test 156 "Verification of tunables"
12964
12965 test_160a() {
12966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12967         remote_mds_nodsh && skip "remote MDS with nodsh"
12968         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12969                 skip "Need MDS version at least 2.2.0"
12970
12971         changelog_register || error "changelog_register failed"
12972         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12973         changelog_users $SINGLEMDS | grep -q $cl_user ||
12974                 error "User $cl_user not found in changelog_users"
12975
12976         # change something
12977         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12978         changelog_clear 0 || error "changelog_clear failed"
12979         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12980         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12981         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12982         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12983         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12984         rm $DIR/$tdir/pics/desktop.jpg
12985
12986         changelog_dump | tail -10
12987
12988         echo "verifying changelog mask"
12989         changelog_chmask "-MKDIR"
12990         changelog_chmask "-CLOSE"
12991
12992         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12993         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12994
12995         changelog_chmask "+MKDIR"
12996         changelog_chmask "+CLOSE"
12997
12998         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12999         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13000
13001         changelog_dump | tail -10
13002         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13003         CLOSES=$(changelog_dump | grep -c "CLOSE")
13004         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13005         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13006
13007         # verify contents
13008         echo "verifying target fid"
13009         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13010         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13011         [ "$fidc" == "$fidf" ] ||
13012                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13013         echo "verifying parent fid"
13014         # The FID returned from the Changelog may be the directory shard on
13015         # a different MDT, and not the FID returned by path2fid on the parent.
13016         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13017         # since this is what will matter when recreating this file in the tree.
13018         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13019         local pathp=$($LFS fid2path $MOUNT "$fidp")
13020         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13021                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13022
13023         echo "getting records for $cl_user"
13024         changelog_users $SINGLEMDS
13025         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13026         local nclr=3
13027         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13028                 error "changelog_clear failed"
13029         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13030         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13031         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13032                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13033
13034         local min0_rec=$(changelog_users $SINGLEMDS |
13035                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13036         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13037                           awk '{ print $1; exit; }')
13038
13039         changelog_dump | tail -n 5
13040         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13041         [ $first_rec == $((min0_rec + 1)) ] ||
13042                 error "first index should be $min0_rec + 1 not $first_rec"
13043
13044         # LU-3446 changelog index reset on MDT restart
13045         local cur_rec1=$(changelog_users $SINGLEMDS |
13046                          awk '/^current.index:/ { print $NF }')
13047         changelog_clear 0 ||
13048                 error "clear all changelog records for $cl_user failed"
13049         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13050         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13051                 error "Fail to start $SINGLEMDS"
13052         local cur_rec2=$(changelog_users $SINGLEMDS |
13053                          awk '/^current.index:/ { print $NF }')
13054         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13055         [ $cur_rec1 == $cur_rec2 ] ||
13056                 error "current index should be $cur_rec1 not $cur_rec2"
13057
13058         echo "verifying users from this test are deregistered"
13059         changelog_deregister || error "changelog_deregister failed"
13060         changelog_users $SINGLEMDS | grep -q $cl_user &&
13061                 error "User '$cl_user' still in changelog_users"
13062
13063         # lctl get_param -n mdd.*.changelog_users
13064         # current index: 144
13065         # ID    index (idle seconds)
13066         # cl3   144 (2)
13067         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13068                 # this is the normal case where all users were deregistered
13069                 # make sure no new records are added when no users are present
13070                 local last_rec1=$(changelog_users $SINGLEMDS |
13071                                   awk '/^current.index:/ { print $NF }')
13072                 touch $DIR/$tdir/chloe
13073                 local last_rec2=$(changelog_users $SINGLEMDS |
13074                                   awk '/^current.index:/ { print $NF }')
13075                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13076                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13077         else
13078                 # any changelog users must be leftovers from a previous test
13079                 changelog_users $SINGLEMDS
13080                 echo "other changelog users; can't verify off"
13081         fi
13082 }
13083 run_test 160a "changelog sanity"
13084
13085 test_160b() { # LU-3587
13086         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13087         remote_mds_nodsh && skip "remote MDS with nodsh"
13088         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13089                 skip "Need MDS version at least 2.2.0"
13090
13091         changelog_register || error "changelog_register failed"
13092         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13093         changelog_users $SINGLEMDS | grep -q $cl_user ||
13094                 error "User '$cl_user' not found in changelog_users"
13095
13096         local longname1=$(str_repeat a 255)
13097         local longname2=$(str_repeat b 255)
13098
13099         cd $DIR
13100         echo "creating very long named file"
13101         touch $longname1 || error "create of '$longname1' failed"
13102         echo "renaming very long named file"
13103         mv $longname1 $longname2
13104
13105         changelog_dump | grep RENME | tail -n 5
13106         rm -f $longname2
13107 }
13108 run_test 160b "Verify that very long rename doesn't crash in changelog"
13109
13110 test_160c() {
13111         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13112         remote_mds_nodsh && skip "remote MDS with nodsh"
13113
13114         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13115                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13116                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13117                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13118
13119         local rc=0
13120
13121         # Registration step
13122         changelog_register || error "changelog_register failed"
13123
13124         rm -rf $DIR/$tdir
13125         mkdir -p $DIR/$tdir
13126         $MCREATE $DIR/$tdir/foo_160c
13127         changelog_chmask "-TRUNC"
13128         $TRUNCATE $DIR/$tdir/foo_160c 200
13129         changelog_chmask "+TRUNC"
13130         $TRUNCATE $DIR/$tdir/foo_160c 199
13131         changelog_dump | tail -n 5
13132         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13133         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13134 }
13135 run_test 160c "verify that changelog log catch the truncate event"
13136
13137 test_160d() {
13138         remote_mds_nodsh && skip "remote MDS with nodsh"
13139         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13141         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13142                 skip "Need MDS version at least 2.7.60"
13143
13144         # Registration step
13145         changelog_register || error "changelog_register failed"
13146
13147         mkdir -p $DIR/$tdir/migrate_dir
13148         changelog_clear 0 || error "changelog_clear failed"
13149
13150         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13151         changelog_dump | tail -n 5
13152         local migrates=$(changelog_dump | grep -c "MIGRT")
13153         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13154 }
13155 run_test 160d "verify that changelog log catch the migrate event"
13156
13157 test_160e() {
13158         remote_mds_nodsh && skip "remote MDS with nodsh"
13159
13160         # Create a user
13161         changelog_register || error "changelog_register failed"
13162
13163         # Delete a future user (expect fail)
13164         local MDT0=$(facet_svc $SINGLEMDS)
13165         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13166         local rc=$?
13167
13168         if [ $rc -eq 0 ]; then
13169                 error "Deleted non-existant user cl77"
13170         elif [ $rc -ne 2 ]; then
13171                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13172         fi
13173
13174         # Clear to a bad index (1 billion should be safe)
13175         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13176         rc=$?
13177
13178         if [ $rc -eq 0 ]; then
13179                 error "Successfully cleared to invalid CL index"
13180         elif [ $rc -ne 22 ]; then
13181                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13182         fi
13183 }
13184 run_test 160e "changelog negative testing (should return errors)"
13185
13186 test_160f() {
13187         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13188         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13189                 skip "Need MDS version at least 2.10.56"
13190
13191         local mdts=$(comma_list $(mdts_nodes))
13192
13193         # Create a user
13194         changelog_register || error "first changelog_register failed"
13195         changelog_register || error "second changelog_register failed"
13196         local cl_users
13197         declare -A cl_user1
13198         declare -A cl_user2
13199         local user_rec1
13200         local user_rec2
13201         local i
13202
13203         # generate some changelog records to accumulate on each MDT
13204         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13205         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13206                 error "create $DIR/$tdir/$tfile failed"
13207
13208         # check changelogs have been generated
13209         local nbcl=$(changelog_dump | wc -l)
13210         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13211
13212         for param in "changelog_max_idle_time=10" \
13213                      "changelog_gc=1" \
13214                      "changelog_min_gc_interval=2" \
13215                      "changelog_min_free_cat_entries=3"; do
13216                 local MDT0=$(facet_svc $SINGLEMDS)
13217                 local var="${param%=*}"
13218                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13219
13220                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13221                 do_nodes $mdts $LCTL set_param mdd.*.$param
13222         done
13223
13224         # force cl_user2 to be idle (1st part)
13225         sleep 9
13226
13227         # simulate changelog catalog almost full
13228         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13229         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13230
13231         for i in $(seq $MDSCOUNT); do
13232                 cl_users=(${CL_USERS[mds$i]})
13233                 cl_user1[mds$i]="${cl_users[0]}"
13234                 cl_user2[mds$i]="${cl_users[1]}"
13235
13236                 [ -n "${cl_user1[mds$i]}" ] ||
13237                         error "mds$i: no user registered"
13238                 [ -n "${cl_user2[mds$i]}" ] ||
13239                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13240
13241                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13242                 [ -n "$user_rec1" ] ||
13243                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13244                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13245                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13246                 [ -n "$user_rec2" ] ||
13247                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13248                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13249                      "$user_rec1 + 2 == $user_rec2"
13250                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13251                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13252                               "$user_rec1 + 2, but is $user_rec2"
13253                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13254                 [ -n "$user_rec2" ] ||
13255                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13256                 [ $user_rec1 == $user_rec2 ] ||
13257                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13258                               "$user_rec1, but is $user_rec2"
13259         done
13260
13261         # force cl_user2 to be idle (2nd part) and to reach
13262         # changelog_max_idle_time
13263         sleep 2
13264
13265         # generate one more changelog to trigger fail_loc
13266         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13267                 error "create $DIR/$tdir/${tfile}bis failed"
13268
13269         # ensure gc thread is done
13270         for i in $(mdts_nodes); do
13271                 wait_update $i \
13272                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13273                         error "$i: GC-thread not done"
13274         done
13275
13276         local first_rec
13277         for i in $(seq $MDSCOUNT); do
13278                 # check cl_user1 still registered
13279                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13280                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13281                 # check cl_user2 unregistered
13282                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13283                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13284
13285                 # check changelogs are present and starting at $user_rec1 + 1
13286                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13287                 [ -n "$user_rec1" ] ||
13288                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13289                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13290                             awk '{ print $1; exit; }')
13291
13292                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13293                 [ $((user_rec1 + 1)) == $first_rec ] ||
13294                         error "mds$i: first index should be $user_rec1 + 1, " \
13295                               "but is $first_rec"
13296         done
13297 }
13298 run_test 160f "changelog garbage collect (timestamped users)"
13299
13300 test_160g() {
13301         remote_mds_nodsh && skip "remote MDS with nodsh"
13302         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13303                 skip "Need MDS version at least 2.10.56"
13304
13305         local mdts=$(comma_list $(mdts_nodes))
13306
13307         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13308         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13309
13310         # Create a user
13311         changelog_register || error "first changelog_register failed"
13312         changelog_register || error "second changelog_register failed"
13313         local cl_users
13314         declare -A cl_user1
13315         declare -A cl_user2
13316         local user_rec1
13317         local user_rec2
13318         local i
13319
13320         # generate some changelog records to accumulate on each MDT
13321         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13322         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13323                 error "create $DIR/$tdir/$tfile failed"
13324
13325         # check changelogs have been generated
13326         local nbcl=$(changelog_dump | wc -l)
13327         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13328
13329         # reduce the max_idle_indexes value to make sure we exceed it
13330         max_ndx=$((nbcl / 2 - 1))
13331
13332         for param in "changelog_max_idle_indexes=$max_ndx" \
13333                      "changelog_gc=1" \
13334                      "changelog_min_gc_interval=2" \
13335                      "changelog_min_free_cat_entries=3"; do
13336                 local MDT0=$(facet_svc $SINGLEMDS)
13337                 local var="${param%=*}"
13338                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13339
13340                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13341                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13342                         error "unable to set mdd.*.$param"
13343         done
13344
13345         # simulate changelog catalog almost full
13346         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13347         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13348
13349         for i in $(seq $MDSCOUNT); do
13350                 cl_users=(${CL_USERS[mds$i]})
13351                 cl_user1[mds$i]="${cl_users[0]}"
13352                 cl_user2[mds$i]="${cl_users[1]}"
13353
13354                 [ -n "${cl_user1[mds$i]}" ] ||
13355                         error "mds$i: no user registered"
13356                 [ -n "${cl_user2[mds$i]}" ] ||
13357                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13358
13359                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13360                 [ -n "$user_rec1" ] ||
13361                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13362                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13363                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13364                 [ -n "$user_rec2" ] ||
13365                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13366                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13367                      "$user_rec1 + 2 == $user_rec2"
13368                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13369                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13370                               "$user_rec1 + 2, but is $user_rec2"
13371                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13372                 [ -n "$user_rec2" ] ||
13373                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13374                 [ $user_rec1 == $user_rec2 ] ||
13375                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13376                               "$user_rec1, but is $user_rec2"
13377         done
13378
13379         # ensure we are past the previous changelog_min_gc_interval set above
13380         sleep 2
13381
13382         # generate one more changelog to trigger fail_loc
13383         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13384                 error "create $DIR/$tdir/${tfile}bis failed"
13385
13386         # ensure gc thread is done
13387         for i in $(mdts_nodes); do
13388                 wait_update $i \
13389                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13390                         error "$i: GC-thread not done"
13391         done
13392
13393         local first_rec
13394         for i in $(seq $MDSCOUNT); do
13395                 # check cl_user1 still registered
13396                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13397                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13398                 # check cl_user2 unregistered
13399                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13400                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13401
13402                 # check changelogs are present and starting at $user_rec1 + 1
13403                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13404                 [ -n "$user_rec1" ] ||
13405                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13406                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13407                             awk '{ print $1; exit; }')
13408
13409                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13410                 [ $((user_rec1 + 1)) == $first_rec ] ||
13411                         error "mds$i: first index should be $user_rec1 + 1, " \
13412                               "but is $first_rec"
13413         done
13414 }
13415 run_test 160g "changelog garbage collect (old users)"
13416
13417 test_160h() {
13418         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13419         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13420                 skip "Need MDS version at least 2.10.56"
13421
13422         local mdts=$(comma_list $(mdts_nodes))
13423
13424         # Create a user
13425         changelog_register || error "first changelog_register failed"
13426         changelog_register || error "second changelog_register failed"
13427         local cl_users
13428         declare -A cl_user1
13429         declare -A cl_user2
13430         local user_rec1
13431         local user_rec2
13432         local i
13433
13434         # generate some changelog records to accumulate on each MDT
13435         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13436         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13437                 error "create $DIR/$tdir/$tfile failed"
13438
13439         # check changelogs have been generated
13440         local nbcl=$(changelog_dump | wc -l)
13441         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13442
13443         for param in "changelog_max_idle_time=10" \
13444                      "changelog_gc=1" \
13445                      "changelog_min_gc_interval=2"; do
13446                 local MDT0=$(facet_svc $SINGLEMDS)
13447                 local var="${param%=*}"
13448                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13449
13450                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13451                 do_nodes $mdts $LCTL set_param mdd.*.$param
13452         done
13453
13454         # force cl_user2 to be idle (1st part)
13455         sleep 9
13456
13457         for i in $(seq $MDSCOUNT); do
13458                 cl_users=(${CL_USERS[mds$i]})
13459                 cl_user1[mds$i]="${cl_users[0]}"
13460                 cl_user2[mds$i]="${cl_users[1]}"
13461
13462                 [ -n "${cl_user1[mds$i]}" ] ||
13463                         error "mds$i: no user registered"
13464                 [ -n "${cl_user2[mds$i]}" ] ||
13465                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13466
13467                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13468                 [ -n "$user_rec1" ] ||
13469                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13470                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13471                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13472                 [ -n "$user_rec2" ] ||
13473                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13474                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13475                      "$user_rec1 + 2 == $user_rec2"
13476                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13477                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13478                               "$user_rec1 + 2, but is $user_rec2"
13479                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13480                 [ -n "$user_rec2" ] ||
13481                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13482                 [ $user_rec1 == $user_rec2 ] ||
13483                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13484                               "$user_rec1, but is $user_rec2"
13485         done
13486
13487         # force cl_user2 to be idle (2nd part) and to reach
13488         # changelog_max_idle_time
13489         sleep 2
13490
13491         # force each GC-thread start and block then
13492         # one per MDT/MDD, set fail_val accordingly
13493         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13494         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13495
13496         # generate more changelogs to trigger fail_loc
13497         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13498                 error "create $DIR/$tdir/${tfile}bis failed"
13499
13500         # stop MDT to stop GC-thread, should be done in back-ground as it will
13501         # block waiting for the thread to be released and exit
13502         declare -A stop_pids
13503         for i in $(seq $MDSCOUNT); do
13504                 stop mds$i &
13505                 stop_pids[mds$i]=$!
13506         done
13507
13508         for i in $(mdts_nodes); do
13509                 local facet
13510                 local nb=0
13511                 local facets=$(facets_up_on_host $i)
13512
13513                 for facet in ${facets//,/ }; do
13514                         if [[ $facet == mds* ]]; then
13515                                 nb=$((nb + 1))
13516                         fi
13517                 done
13518                 # ensure each MDS's gc threads are still present and all in "R"
13519                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13520                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13521                         error "$i: expected $nb GC-thread"
13522                 wait_update $i \
13523                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13524                         "R" 20 ||
13525                         error "$i: GC-thread not found in R-state"
13526                 # check umounts of each MDT on MDS have reached kthread_stop()
13527                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13528                         error "$i: expected $nb umount"
13529                 wait_update $i \
13530                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13531                         error "$i: umount not found in D-state"
13532         done
13533
13534         # release all GC-threads
13535         do_nodes $mdts $LCTL set_param fail_loc=0
13536
13537         # wait for MDT stop to complete
13538         for i in $(seq $MDSCOUNT); do
13539                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13540         done
13541
13542         # XXX
13543         # may try to check if any orphan changelog records are present
13544         # via ldiskfs/zfs and llog_reader...
13545
13546         # re-start/mount MDTs
13547         for i in $(seq $MDSCOUNT); do
13548                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13549                         error "Fail to start mds$i"
13550         done
13551
13552         local first_rec
13553         for i in $(seq $MDSCOUNT); do
13554                 # check cl_user1 still registered
13555                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13556                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13557                 # check cl_user2 unregistered
13558                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13559                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13560
13561                 # check changelogs are present and starting at $user_rec1 + 1
13562                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13563                 [ -n "$user_rec1" ] ||
13564                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13565                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13566                             awk '{ print $1; exit; }')
13567
13568                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13569                 [ $((user_rec1 + 1)) == $first_rec ] ||
13570                         error "mds$i: first index should be $user_rec1 + 1, " \
13571                               "but is $first_rec"
13572         done
13573 }
13574 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13575               "during mount"
13576
13577 test_160i() {
13578
13579         local mdts=$(comma_list $(mdts_nodes))
13580
13581         changelog_register || error "first changelog_register failed"
13582
13583         # generate some changelog records to accumulate on each MDT
13584         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13585         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13586                 error "create $DIR/$tdir/$tfile failed"
13587
13588         # check changelogs have been generated
13589         local nbcl=$(changelog_dump | wc -l)
13590         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13591
13592         # simulate race between register and unregister
13593         # XXX as fail_loc is set per-MDS, with DNE configs the race
13594         # simulation will only occur for one MDT per MDS and for the
13595         # others the normal race scenario will take place
13596         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13597         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13598         do_nodes $mdts $LCTL set_param fail_val=1
13599
13600         # unregister 1st user
13601         changelog_deregister &
13602         local pid1=$!
13603         # wait some time for deregister work to reach race rdv
13604         sleep 2
13605         # register 2nd user
13606         changelog_register || error "2nd user register failed"
13607
13608         wait $pid1 || error "1st user deregister failed"
13609
13610         local i
13611         local last_rec
13612         declare -A LAST_REC
13613         for i in $(seq $MDSCOUNT); do
13614                 if changelog_users mds$i | grep "^cl"; then
13615                         # make sure new records are added with one user present
13616                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13617                                           awk '/^current.index:/ { print $NF }')
13618                 else
13619                         error "mds$i has no user registered"
13620                 fi
13621         done
13622
13623         # generate more changelog records to accumulate on each MDT
13624         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13625                 error "create $DIR/$tdir/${tfile}bis failed"
13626
13627         for i in $(seq $MDSCOUNT); do
13628                 last_rec=$(changelog_users $SINGLEMDS |
13629                            awk '/^current.index:/ { print $NF }')
13630                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13631                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13632                         error "changelogs are off on mds$i"
13633         done
13634 }
13635 run_test 160i "changelog user register/unregister race"
13636
13637 test_161a() {
13638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13639
13640         test_mkdir -c1 $DIR/$tdir
13641         cp /etc/hosts $DIR/$tdir/$tfile
13642         test_mkdir -c1 $DIR/$tdir/foo1
13643         test_mkdir -c1 $DIR/$tdir/foo2
13644         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13645         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13646         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13647         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13648         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13649         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13650                 $LFS fid2path $DIR $FID
13651                 error "bad link ea"
13652         fi
13653         # middle
13654         rm $DIR/$tdir/foo2/zachary
13655         # last
13656         rm $DIR/$tdir/foo2/thor
13657         # first
13658         rm $DIR/$tdir/$tfile
13659         # rename
13660         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13661         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13662                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13663         rm $DIR/$tdir/foo2/maggie
13664
13665         # overflow the EA
13666         local longname=$tfile.avg_len_is_thirty_two_
13667         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13668                 error_noexit 'failed to unlink many hardlinks'" EXIT
13669         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13670                 error "failed to hardlink many files"
13671         links=$($LFS fid2path $DIR $FID | wc -l)
13672         echo -n "${links}/1000 links in link EA"
13673         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13674 }
13675 run_test 161a "link ea sanity"
13676
13677 test_161b() {
13678         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13679         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13680
13681         local MDTIDX=1
13682         local remote_dir=$DIR/$tdir/remote_dir
13683
13684         mkdir -p $DIR/$tdir
13685         $LFS mkdir -i $MDTIDX $remote_dir ||
13686                 error "create remote directory failed"
13687
13688         cp /etc/hosts $remote_dir/$tfile
13689         mkdir -p $remote_dir/foo1
13690         mkdir -p $remote_dir/foo2
13691         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13692         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13693         ln $remote_dir/$tfile $remote_dir/foo1/luna
13694         ln $remote_dir/$tfile $remote_dir/foo2/thor
13695
13696         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13697                      tr -d ']')
13698         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13699                 $LFS fid2path $DIR $FID
13700                 error "bad link ea"
13701         fi
13702         # middle
13703         rm $remote_dir/foo2/zachary
13704         # last
13705         rm $remote_dir/foo2/thor
13706         # first
13707         rm $remote_dir/$tfile
13708         # rename
13709         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13710         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13711         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13712                 $LFS fid2path $DIR $FID
13713                 error "bad link rename"
13714         fi
13715         rm $remote_dir/foo2/maggie
13716
13717         # overflow the EA
13718         local longname=filename_avg_len_is_thirty_two_
13719         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13720                 error "failed to hardlink many files"
13721         links=$($LFS fid2path $DIR $FID | wc -l)
13722         echo -n "${links}/1000 links in link EA"
13723         [[ ${links} -gt 60 ]] ||
13724                 error "expected at least 60 links in link EA"
13725         unlinkmany $remote_dir/foo2/$longname 1000 ||
13726         error "failed to unlink many hardlinks"
13727 }
13728 run_test 161b "link ea sanity under remote directory"
13729
13730 test_161c() {
13731         remote_mds_nodsh && skip "remote MDS with nodsh"
13732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13733         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13734                 skip "Need MDS version at least 2.1.5"
13735
13736         # define CLF_RENAME_LAST 0x0001
13737         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13738         changelog_register || error "changelog_register failed"
13739
13740         rm -rf $DIR/$tdir
13741         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13742         touch $DIR/$tdir/foo_161c
13743         touch $DIR/$tdir/bar_161c
13744         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13745         changelog_dump | grep RENME | tail -n 5
13746         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13747         changelog_clear 0 || error "changelog_clear failed"
13748         if [ x$flags != "x0x1" ]; then
13749                 error "flag $flags is not 0x1"
13750         fi
13751
13752         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13753         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13754         touch $DIR/$tdir/foo_161c
13755         touch $DIR/$tdir/bar_161c
13756         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13757         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13758         changelog_dump | grep RENME | tail -n 5
13759         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13760         changelog_clear 0 || error "changelog_clear failed"
13761         if [ x$flags != "x0x0" ]; then
13762                 error "flag $flags is not 0x0"
13763         fi
13764         echo "rename overwrite a target having nlink > 1," \
13765                 "changelog record has flags of $flags"
13766
13767         # rename doesn't overwrite a target (changelog flag 0x0)
13768         touch $DIR/$tdir/foo_161c
13769         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13770         changelog_dump | grep RENME | tail -n 5
13771         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13772         changelog_clear 0 || error "changelog_clear failed"
13773         if [ x$flags != "x0x0" ]; then
13774                 error "flag $flags is not 0x0"
13775         fi
13776         echo "rename doesn't overwrite a target," \
13777                 "changelog record has flags of $flags"
13778
13779         # define CLF_UNLINK_LAST 0x0001
13780         # unlink a file having nlink = 1 (changelog flag 0x1)
13781         rm -f $DIR/$tdir/foo2_161c
13782         changelog_dump | grep UNLNK | tail -n 5
13783         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13784         changelog_clear 0 || error "changelog_clear failed"
13785         if [ x$flags != "x0x1" ]; then
13786                 error "flag $flags is not 0x1"
13787         fi
13788         echo "unlink a file having nlink = 1," \
13789                 "changelog record has flags of $flags"
13790
13791         # unlink a file having nlink > 1 (changelog flag 0x0)
13792         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13793         rm -f $DIR/$tdir/foobar_161c
13794         changelog_dump | grep UNLNK | tail -n 5
13795         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13796         changelog_clear 0 || error "changelog_clear failed"
13797         if [ x$flags != "x0x0" ]; then
13798                 error "flag $flags is not 0x0"
13799         fi
13800         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13801 }
13802 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13803
13804 test_161d() {
13805         remote_mds_nodsh && skip "remote MDS with nodsh"
13806         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13807
13808         local pid
13809         local fid
13810
13811         changelog_register || error "changelog_register failed"
13812
13813         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13814         # interfer with $MOUNT/.lustre/fid/ access
13815         mkdir $DIR/$tdir
13816         [[ $? -eq 0 ]] || error "mkdir failed"
13817
13818         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13819         $LCTL set_param fail_loc=0x8000140c
13820         # 5s pause
13821         $LCTL set_param fail_val=5
13822
13823         # create file
13824         echo foofoo > $DIR/$tdir/$tfile &
13825         pid=$!
13826
13827         # wait for create to be delayed
13828         sleep 2
13829
13830         ps -p $pid
13831         [[ $? -eq 0 ]] || error "create should be blocked"
13832
13833         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
13834         stack_trap "rm -f $tempfile"
13835         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13836         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13837         # some delay may occur during ChangeLog publishing and file read just
13838         # above, that could allow file write to happen finally
13839         [[ -s $tempfile ]] && echo "file should be empty"
13840
13841         $LCTL set_param fail_loc=0
13842
13843         wait $pid
13844         [[ $? -eq 0 ]] || error "create failed"
13845 }
13846 run_test 161d "create with concurrent .lustre/fid access"
13847
13848 check_path() {
13849         local expected="$1"
13850         shift
13851         local fid="$2"
13852
13853         local path
13854         path=$($LFS fid2path "$@")
13855         local rc=$?
13856
13857         if [ $rc -ne 0 ]; then
13858                 error "path looked up of '$expected' failed: rc=$rc"
13859         elif [ "$path" != "$expected" ]; then
13860                 error "path looked up '$path' instead of '$expected'"
13861         else
13862                 echo "FID '$fid' resolves to path '$path' as expected"
13863         fi
13864 }
13865
13866 test_162a() { # was test_162
13867         test_mkdir -p -c1 $DIR/$tdir/d2
13868         touch $DIR/$tdir/d2/$tfile
13869         touch $DIR/$tdir/d2/x1
13870         touch $DIR/$tdir/d2/x2
13871         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13872         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13873         # regular file
13874         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13875         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13876
13877         # softlink
13878         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13879         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13880         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13881
13882         # softlink to wrong file
13883         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13884         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13885         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13886
13887         # hardlink
13888         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13889         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13890         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13891         # fid2path dir/fsname should both work
13892         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13893         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13894
13895         # hardlink count: check that there are 2 links
13896         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13897         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13898
13899         # hardlink indexing: remove the first link
13900         rm $DIR/$tdir/d2/p/q/r/hlink
13901         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13902 }
13903 run_test 162a "path lookup sanity"
13904
13905 test_162b() {
13906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13907         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13908
13909         mkdir $DIR/$tdir
13910         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13911                                 error "create striped dir failed"
13912
13913         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13914                                         tail -n 1 | awk '{print $2}')
13915         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13916
13917         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13918         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13919
13920         # regular file
13921         for ((i=0;i<5;i++)); do
13922                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13923                         error "get fid for f$i failed"
13924                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13925
13926                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13927                         error "get fid for d$i failed"
13928                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13929         done
13930
13931         return 0
13932 }
13933 run_test 162b "striped directory path lookup sanity"
13934
13935 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13936 test_162c() {
13937         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13938                 skip "Need MDS version at least 2.7.51"
13939
13940         local lpath=$tdir.local
13941         local rpath=$tdir.remote
13942
13943         test_mkdir $DIR/$lpath
13944         test_mkdir $DIR/$rpath
13945
13946         for ((i = 0; i <= 101; i++)); do
13947                 lpath="$lpath/$i"
13948                 mkdir $DIR/$lpath
13949                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13950                         error "get fid for local directory $DIR/$lpath failed"
13951                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13952
13953                 rpath="$rpath/$i"
13954                 test_mkdir $DIR/$rpath
13955                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13956                         error "get fid for remote directory $DIR/$rpath failed"
13957                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13958         done
13959
13960         return 0
13961 }
13962 run_test 162c "fid2path works with paths 100 or more directories deep"
13963
13964 test_169() {
13965         # do directio so as not to populate the page cache
13966         log "creating a 10 Mb file"
13967         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13968         log "starting reads"
13969         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13970         log "truncating the file"
13971         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13972         log "killing dd"
13973         kill %+ || true # reads might have finished
13974         echo "wait until dd is finished"
13975         wait
13976         log "removing the temporary file"
13977         rm -rf $DIR/$tfile || error "tmp file removal failed"
13978 }
13979 run_test 169 "parallel read and truncate should not deadlock"
13980
13981 test_170() {
13982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13983
13984         $LCTL clear     # bug 18514
13985         $LCTL debug_daemon start $TMP/${tfile}_log_good
13986         touch $DIR/$tfile
13987         $LCTL debug_daemon stop
13988         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13989                 error "sed failed to read log_good"
13990
13991         $LCTL debug_daemon start $TMP/${tfile}_log_good
13992         rm -rf $DIR/$tfile
13993         $LCTL debug_daemon stop
13994
13995         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13996                error "lctl df log_bad failed"
13997
13998         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13999         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14000
14001         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14002         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14003
14004         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14005                 error "bad_line good_line1 good_line2 are empty"
14006
14007         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14008         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14009         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14010
14011         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14012         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14013         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14014
14015         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14016                 error "bad_line_new good_line_new are empty"
14017
14018         local expected_good=$((good_line1 + good_line2*2))
14019
14020         rm -f $TMP/${tfile}*
14021         # LU-231, short malformed line may not be counted into bad lines
14022         if [ $bad_line -ne $bad_line_new ] &&
14023                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14024                 error "expected $bad_line bad lines, but got $bad_line_new"
14025                 return 1
14026         fi
14027
14028         if [ $expected_good -ne $good_line_new ]; then
14029                 error "expected $expected_good good lines, but got $good_line_new"
14030                 return 2
14031         fi
14032         true
14033 }
14034 run_test 170 "test lctl df to handle corrupted log ====================="
14035
14036 test_171() { # bug20592
14037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14038
14039         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14040         $LCTL set_param fail_loc=0x50e
14041         $LCTL set_param fail_val=3000
14042         multiop_bg_pause $DIR/$tfile O_s || true
14043         local MULTIPID=$!
14044         kill -USR1 $MULTIPID
14045         # cause log dump
14046         sleep 3
14047         wait $MULTIPID
14048         if dmesg | grep "recursive fault"; then
14049                 error "caught a recursive fault"
14050         fi
14051         $LCTL set_param fail_loc=0
14052         true
14053 }
14054 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14055
14056 # it would be good to share it with obdfilter-survey/iokit-libecho code
14057 setup_obdecho_osc () {
14058         local rc=0
14059         local ost_nid=$1
14060         local obdfilter_name=$2
14061         echo "Creating new osc for $obdfilter_name on $ost_nid"
14062         # make sure we can find loopback nid
14063         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14064
14065         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14066                            ${obdfilter_name}_osc_UUID || rc=2; }
14067         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14068                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14069         return $rc
14070 }
14071
14072 cleanup_obdecho_osc () {
14073         local obdfilter_name=$1
14074         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14075         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14076         return 0
14077 }
14078
14079 obdecho_test() {
14080         local OBD=$1
14081         local node=$2
14082         local pages=${3:-64}
14083         local rc=0
14084         local id
14085
14086         local count=10
14087         local obd_size=$(get_obd_size $node $OBD)
14088         local page_size=$(get_page_size $node)
14089         if [[ -n "$obd_size" ]]; then
14090                 local new_count=$((obd_size / (pages * page_size / 1024)))
14091                 [[ $new_count -ge $count ]] || count=$new_count
14092         fi
14093
14094         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14095         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14096                            rc=2; }
14097         if [ $rc -eq 0 ]; then
14098             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14099             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14100         fi
14101         echo "New object id is $id"
14102         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14103                            rc=4; }
14104         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14105                            "test_brw $count w v $pages $id" || rc=4; }
14106         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14107                            rc=4; }
14108         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14109                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14110         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14111                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14112         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14113         return $rc
14114 }
14115
14116 test_180a() {
14117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14118
14119         if ! module_loaded obdecho; then
14120                 load_module obdecho/obdecho &&
14121                         stack_trap "rmmod obdecho" EXIT ||
14122                         error "unable to load obdecho on client"
14123         fi
14124
14125         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14126         local host=$($LCTL get_param -n osc.$osc.import |
14127                      awk '/current_connection:/ { print $2 }' )
14128         local target=$($LCTL get_param -n osc.$osc.import |
14129                        awk '/target:/ { print $2 }' )
14130         target=${target%_UUID}
14131
14132         if [ -n "$target" ]; then
14133                 setup_obdecho_osc $host $target &&
14134                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14135                         { error "obdecho setup failed with $?"; return; }
14136
14137                 obdecho_test ${target}_osc client ||
14138                         error "obdecho_test failed on ${target}_osc"
14139         else
14140                 $LCTL get_param osc.$osc.import
14141                 error "there is no osc.$osc.import target"
14142         fi
14143 }
14144 run_test 180a "test obdecho on osc"
14145
14146 test_180b() {
14147         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14148         remote_ost_nodsh && skip "remote OST with nodsh"
14149
14150         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14151                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14152                 error "failed to load module obdecho"
14153
14154         local target=$(do_facet ost1 $LCTL dl |
14155                        awk '/obdfilter/ { print $4; exit; }')
14156
14157         if [ -n "$target" ]; then
14158                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14159         else
14160                 do_facet ost1 $LCTL dl
14161                 error "there is no obdfilter target on ost1"
14162         fi
14163 }
14164 run_test 180b "test obdecho directly on obdfilter"
14165
14166 test_180c() { # LU-2598
14167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14168         remote_ost_nodsh && skip "remote OST with nodsh"
14169         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14170                 skip "Need MDS version at least 2.4.0"
14171
14172         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14173                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14174                 error "failed to load module obdecho"
14175
14176         local target=$(do_facet ost1 $LCTL dl |
14177                        awk '/obdfilter/ { print $4; exit; }')
14178
14179         if [ -n "$target" ]; then
14180                 local pages=16384 # 64MB bulk I/O RPC size
14181
14182                 obdecho_test "$target" ost1 "$pages" ||
14183                         error "obdecho_test with pages=$pages failed with $?"
14184         else
14185                 do_facet ost1 $LCTL dl
14186                 error "there is no obdfilter target on ost1"
14187         fi
14188 }
14189 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14190
14191 test_181() { # bug 22177
14192         test_mkdir $DIR/$tdir
14193         # create enough files to index the directory
14194         createmany -o $DIR/$tdir/foobar 4000
14195         # print attributes for debug purpose
14196         lsattr -d .
14197         # open dir
14198         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14199         MULTIPID=$!
14200         # remove the files & current working dir
14201         unlinkmany $DIR/$tdir/foobar 4000
14202         rmdir $DIR/$tdir
14203         kill -USR1 $MULTIPID
14204         wait $MULTIPID
14205         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14206         return 0
14207 }
14208 run_test 181 "Test open-unlinked dir ========================"
14209
14210 test_182() {
14211         local fcount=1000
14212         local tcount=10
14213
14214         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14215
14216         $LCTL set_param mdc.*.rpc_stats=clear
14217
14218         for (( i = 0; i < $tcount; i++ )) ; do
14219                 mkdir $DIR/$tdir/$i
14220         done
14221
14222         for (( i = 0; i < $tcount; i++ )) ; do
14223                 createmany -o $DIR/$tdir/$i/f- $fcount &
14224         done
14225         wait
14226
14227         for (( i = 0; i < $tcount; i++ )) ; do
14228                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14229         done
14230         wait
14231
14232         $LCTL get_param mdc.*.rpc_stats
14233
14234         rm -rf $DIR/$tdir
14235 }
14236 run_test 182 "Test parallel modify metadata operations ================"
14237
14238 test_183() { # LU-2275
14239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14240         remote_mds_nodsh && skip "remote MDS with nodsh"
14241         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14242                 skip "Need MDS version at least 2.3.56"
14243
14244         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14245         echo aaa > $DIR/$tdir/$tfile
14246
14247 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14248         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14249
14250         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14251         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14252
14253         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14254
14255         # Flush negative dentry cache
14256         touch $DIR/$tdir/$tfile
14257
14258         # We are not checking for any leaked references here, they'll
14259         # become evident next time we do cleanup with module unload.
14260         rm -rf $DIR/$tdir
14261 }
14262 run_test 183 "No crash or request leak in case of strange dispositions ========"
14263
14264 # test suite 184 is for LU-2016, LU-2017
14265 test_184a() {
14266         check_swap_layouts_support
14267
14268         dir0=$DIR/$tdir/$testnum
14269         test_mkdir -p -c1 $dir0
14270         ref1=/etc/passwd
14271         ref2=/etc/group
14272         file1=$dir0/f1
14273         file2=$dir0/f2
14274         $LFS setstripe -c1 $file1
14275         cp $ref1 $file1
14276         $LFS setstripe -c2 $file2
14277         cp $ref2 $file2
14278         gen1=$($LFS getstripe -g $file1)
14279         gen2=$($LFS getstripe -g $file2)
14280
14281         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14282         gen=$($LFS getstripe -g $file1)
14283         [[ $gen1 != $gen ]] ||
14284                 "Layout generation on $file1 does not change"
14285         gen=$($LFS getstripe -g $file2)
14286         [[ $gen2 != $gen ]] ||
14287                 "Layout generation on $file2 does not change"
14288
14289         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14290         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14291
14292         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14293 }
14294 run_test 184a "Basic layout swap"
14295
14296 test_184b() {
14297         check_swap_layouts_support
14298
14299         dir0=$DIR/$tdir/$testnum
14300         mkdir -p $dir0 || error "creating dir $dir0"
14301         file1=$dir0/f1
14302         file2=$dir0/f2
14303         file3=$dir0/f3
14304         dir1=$dir0/d1
14305         dir2=$dir0/d2
14306         mkdir $dir1 $dir2
14307         $LFS setstripe -c1 $file1
14308         $LFS setstripe -c2 $file2
14309         $LFS setstripe -c1 $file3
14310         chown $RUNAS_ID $file3
14311         gen1=$($LFS getstripe -g $file1)
14312         gen2=$($LFS getstripe -g $file2)
14313
14314         $LFS swap_layouts $dir1 $dir2 &&
14315                 error "swap of directories layouts should fail"
14316         $LFS swap_layouts $dir1 $file1 &&
14317                 error "swap of directory and file layouts should fail"
14318         $RUNAS $LFS swap_layouts $file1 $file2 &&
14319                 error "swap of file we cannot write should fail"
14320         $LFS swap_layouts $file1 $file3 &&
14321                 error "swap of file with different owner should fail"
14322         /bin/true # to clear error code
14323 }
14324 run_test 184b "Forbidden layout swap (will generate errors)"
14325
14326 test_184c() {
14327         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14328         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14329         check_swap_layouts_support
14330
14331         local dir0=$DIR/$tdir/$testnum
14332         mkdir -p $dir0 || error "creating dir $dir0"
14333
14334         local ref1=$dir0/ref1
14335         local ref2=$dir0/ref2
14336         local file1=$dir0/file1
14337         local file2=$dir0/file2
14338         # create a file large enough for the concurrent test
14339         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14340         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14341         echo "ref file size: ref1($(stat -c %s $ref1))," \
14342              "ref2($(stat -c %s $ref2))"
14343
14344         cp $ref2 $file2
14345         dd if=$ref1 of=$file1 bs=16k &
14346         local DD_PID=$!
14347
14348         # Make sure dd starts to copy file
14349         while [ ! -f $file1 ]; do sleep 0.1; done
14350
14351         $LFS swap_layouts $file1 $file2
14352         local rc=$?
14353         wait $DD_PID
14354         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14355         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14356
14357         # how many bytes copied before swapping layout
14358         local copied=$(stat -c %s $file2)
14359         local remaining=$(stat -c %s $ref1)
14360         remaining=$((remaining - copied))
14361         echo "Copied $copied bytes before swapping layout..."
14362
14363         cmp -n $copied $file1 $ref2 | grep differ &&
14364                 error "Content mismatch [0, $copied) of ref2 and file1"
14365         cmp -n $copied $file2 $ref1 ||
14366                 error "Content mismatch [0, $copied) of ref1 and file2"
14367         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14368                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14369
14370         # clean up
14371         rm -f $ref1 $ref2 $file1 $file2
14372 }
14373 run_test 184c "Concurrent write and layout swap"
14374
14375 test_184d() {
14376         check_swap_layouts_support
14377         [ -z "$(which getfattr 2>/dev/null)" ] &&
14378                 skip_env "no getfattr command"
14379
14380         local file1=$DIR/$tdir/$tfile-1
14381         local file2=$DIR/$tdir/$tfile-2
14382         local file3=$DIR/$tdir/$tfile-3
14383         local lovea1
14384         local lovea2
14385
14386         mkdir -p $DIR/$tdir
14387         touch $file1 || error "create $file1 failed"
14388         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14389                 error "create $file2 failed"
14390         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14391                 error "create $file3 failed"
14392         lovea1=$(get_layout_param $file1)
14393
14394         $LFS swap_layouts $file2 $file3 ||
14395                 error "swap $file2 $file3 layouts failed"
14396         $LFS swap_layouts $file1 $file2 ||
14397                 error "swap $file1 $file2 layouts failed"
14398
14399         lovea2=$(get_layout_param $file2)
14400         echo "$lovea1"
14401         echo "$lovea2"
14402         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14403
14404         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14405         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14406 }
14407 run_test 184d "allow stripeless layouts swap"
14408
14409 test_184e() {
14410         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14411                 skip "Need MDS version at least 2.6.94"
14412         check_swap_layouts_support
14413         [ -z "$(which getfattr 2>/dev/null)" ] &&
14414                 skip_env "no getfattr command"
14415
14416         local file1=$DIR/$tdir/$tfile-1
14417         local file2=$DIR/$tdir/$tfile-2
14418         local file3=$DIR/$tdir/$tfile-3
14419         local lovea
14420
14421         mkdir -p $DIR/$tdir
14422         touch $file1 || error "create $file1 failed"
14423         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14424                 error "create $file2 failed"
14425         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14426                 error "create $file3 failed"
14427
14428         $LFS swap_layouts $file1 $file2 ||
14429                 error "swap $file1 $file2 layouts failed"
14430
14431         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14432         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14433
14434         echo 123 > $file1 || error "Should be able to write into $file1"
14435
14436         $LFS swap_layouts $file1 $file3 ||
14437                 error "swap $file1 $file3 layouts failed"
14438
14439         echo 123 > $file1 || error "Should be able to write into $file1"
14440
14441         rm -rf $file1 $file2 $file3
14442 }
14443 run_test 184e "Recreate layout after stripeless layout swaps"
14444
14445 test_184f() {
14446         # Create a file with name longer than sizeof(struct stat) ==
14447         # 144 to see if we can get chars from the file name to appear
14448         # in the returned striping. Note that 'f' == 0x66.
14449         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14450
14451         mkdir -p $DIR/$tdir
14452         mcreate $DIR/$tdir/$file
14453         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14454                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14455         fi
14456 }
14457 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14458
14459 test_185() { # LU-2441
14460         # LU-3553 - no volatile file support in old servers
14461         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14462                 skip "Need MDS version at least 2.3.60"
14463
14464         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14465         touch $DIR/$tdir/spoo
14466         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14467         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14468                 error "cannot create/write a volatile file"
14469         [ "$FILESET" == "" ] &&
14470         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14471                 error "FID is still valid after close"
14472
14473         multiop_bg_pause $DIR/$tdir vVw4096_c
14474         local multi_pid=$!
14475
14476         local OLD_IFS=$IFS
14477         IFS=":"
14478         local fidv=($fid)
14479         IFS=$OLD_IFS
14480         # assume that the next FID for this client is sequential, since stdout
14481         # is unfortunately eaten by multiop_bg_pause
14482         local n=$((${fidv[1]} + 1))
14483         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14484         if [ "$FILESET" == "" ]; then
14485                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14486                         error "FID is missing before close"
14487         fi
14488         kill -USR1 $multi_pid
14489         # 1 second delay, so if mtime change we will see it
14490         sleep 1
14491         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14492         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14493 }
14494 run_test 185 "Volatile file support"
14495
14496 function create_check_volatile() {
14497         local idx=$1
14498         local tgt
14499
14500         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
14501         local PID=$!
14502         sleep 1
14503         local FID=$(cat /tmp/${tfile}.fid)
14504         [ "$FID" == "" ] && error "can't get FID for volatile"
14505         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
14506         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
14507         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
14508         kill -USR1 $PID
14509         wait
14510         sleep 1
14511         cancel_lru_locks mdc # flush opencache
14512         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
14513         return 0
14514 }
14515
14516 test_185a(){
14517         # LU-12516 - volatile creation via .lustre
14518         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
14519                 skip "Need MDS version at least 2.3.55"
14520
14521         create_check_volatile 0
14522         [ $MDSCOUNT -lt 2 ] && return 0
14523
14524         # DNE case
14525         create_check_volatile 1
14526
14527         return 0
14528 }
14529 run_test 185a "Volatile file creation in .lustre/fid/"
14530
14531 test_187a() {
14532         remote_mds_nodsh && skip "remote MDS with nodsh"
14533         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14534                 skip "Need MDS version at least 2.3.0"
14535
14536         local dir0=$DIR/$tdir/$testnum
14537         mkdir -p $dir0 || error "creating dir $dir0"
14538
14539         local file=$dir0/file1
14540         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14541         local dv1=$($LFS data_version $file)
14542         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14543         local dv2=$($LFS data_version $file)
14544         [[ $dv1 != $dv2 ]] ||
14545                 error "data version did not change on write $dv1 == $dv2"
14546
14547         # clean up
14548         rm -f $file1
14549 }
14550 run_test 187a "Test data version change"
14551
14552 test_187b() {
14553         remote_mds_nodsh && skip "remote MDS with nodsh"
14554         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14555                 skip "Need MDS version at least 2.3.0"
14556
14557         local dir0=$DIR/$tdir/$testnum
14558         mkdir -p $dir0 || error "creating dir $dir0"
14559
14560         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14561         [[ ${DV[0]} != ${DV[1]} ]] ||
14562                 error "data version did not change on write"\
14563                       " ${DV[0]} == ${DV[1]}"
14564
14565         # clean up
14566         rm -f $file1
14567 }
14568 run_test 187b "Test data version change on volatile file"
14569
14570 test_200() {
14571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14572         remote_mgs_nodsh && skip "remote MGS with nodsh"
14573         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14574
14575         local POOL=${POOL:-cea1}
14576         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14577         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14578         # Pool OST targets
14579         local first_ost=0
14580         local last_ost=$(($OSTCOUNT - 1))
14581         local ost_step=2
14582         local ost_list=$(seq $first_ost $ost_step $last_ost)
14583         local ost_range="$first_ost $last_ost $ost_step"
14584         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14585         local file_dir=$POOL_ROOT/file_tst
14586         local subdir=$test_path/subdir
14587         local rc=0
14588
14589         if ! combined_mgs_mds ; then
14590                 mount_mgs_client
14591         fi
14592
14593         while : ; do
14594                 # former test_200a test_200b
14595                 pool_add $POOL                          || { rc=$? ; break; }
14596                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14597                 # former test_200c test_200d
14598                 mkdir -p $test_path
14599                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14600                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14601                 mkdir -p $subdir
14602                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14603                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14604                                                         || { rc=$? ; break; }
14605                 # former test_200e test_200f
14606                 local files=$((OSTCOUNT*3))
14607                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14608                                                         || { rc=$? ; break; }
14609                 pool_create_files $POOL $file_dir $files "$ost_list" \
14610                                                         || { rc=$? ; break; }
14611                 # former test_200g test_200h
14612                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14613                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14614
14615                 # former test_201a test_201b test_201c
14616                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14617
14618                 local f=$test_path/$tfile
14619                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14620                 pool_remove $POOL $f                    || { rc=$? ; break; }
14621                 break
14622         done
14623
14624         destroy_test_pools
14625
14626         if ! combined_mgs_mds ; then
14627                 umount_mgs_client
14628         fi
14629         return $rc
14630 }
14631 run_test 200 "OST pools"
14632
14633 # usage: default_attr <count | size | offset>
14634 default_attr() {
14635         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14636 }
14637
14638 # usage: check_default_stripe_attr
14639 check_default_stripe_attr() {
14640         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14641         case $1 in
14642         --stripe-count|-c)
14643                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14644         --stripe-size|-S)
14645                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14646         --stripe-index|-i)
14647                 EXPECTED=-1;;
14648         *)
14649                 error "unknown getstripe attr '$1'"
14650         esac
14651
14652         [ $ACTUAL == $EXPECTED ] ||
14653                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14654 }
14655
14656 test_204a() {
14657         test_mkdir $DIR/$tdir
14658         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14659
14660         check_default_stripe_attr --stripe-count
14661         check_default_stripe_attr --stripe-size
14662         check_default_stripe_attr --stripe-index
14663 }
14664 run_test 204a "Print default stripe attributes"
14665
14666 test_204b() {
14667         test_mkdir $DIR/$tdir
14668         $LFS setstripe --stripe-count 1 $DIR/$tdir
14669
14670         check_default_stripe_attr --stripe-size
14671         check_default_stripe_attr --stripe-index
14672 }
14673 run_test 204b "Print default stripe size and offset"
14674
14675 test_204c() {
14676         test_mkdir $DIR/$tdir
14677         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14678
14679         check_default_stripe_attr --stripe-count
14680         check_default_stripe_attr --stripe-index
14681 }
14682 run_test 204c "Print default stripe count and offset"
14683
14684 test_204d() {
14685         test_mkdir $DIR/$tdir
14686         $LFS setstripe --stripe-index 0 $DIR/$tdir
14687
14688         check_default_stripe_attr --stripe-count
14689         check_default_stripe_attr --stripe-size
14690 }
14691 run_test 204d "Print default stripe count and size"
14692
14693 test_204e() {
14694         test_mkdir $DIR/$tdir
14695         $LFS setstripe -d $DIR/$tdir
14696
14697         check_default_stripe_attr --stripe-count --raw
14698         check_default_stripe_attr --stripe-size --raw
14699         check_default_stripe_attr --stripe-index --raw
14700 }
14701 run_test 204e "Print raw stripe attributes"
14702
14703 test_204f() {
14704         test_mkdir $DIR/$tdir
14705         $LFS setstripe --stripe-count 1 $DIR/$tdir
14706
14707         check_default_stripe_attr --stripe-size --raw
14708         check_default_stripe_attr --stripe-index --raw
14709 }
14710 run_test 204f "Print raw stripe size and offset"
14711
14712 test_204g() {
14713         test_mkdir $DIR/$tdir
14714         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14715
14716         check_default_stripe_attr --stripe-count --raw
14717         check_default_stripe_attr --stripe-index --raw
14718 }
14719 run_test 204g "Print raw stripe count and offset"
14720
14721 test_204h() {
14722         test_mkdir $DIR/$tdir
14723         $LFS setstripe --stripe-index 0 $DIR/$tdir
14724
14725         check_default_stripe_attr --stripe-count --raw
14726         check_default_stripe_attr --stripe-size --raw
14727 }
14728 run_test 204h "Print raw stripe count and size"
14729
14730 # Figure out which job scheduler is being used, if any,
14731 # or use a fake one
14732 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14733         JOBENV=SLURM_JOB_ID
14734 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14735         JOBENV=LSB_JOBID
14736 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14737         JOBENV=PBS_JOBID
14738 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14739         JOBENV=LOADL_STEP_ID
14740 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14741         JOBENV=JOB_ID
14742 else
14743         $LCTL list_param jobid_name > /dev/null 2>&1
14744         if [ $? -eq 0 ]; then
14745                 JOBENV=nodelocal
14746         else
14747                 JOBENV=FAKE_JOBID
14748         fi
14749 fi
14750 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14751
14752 verify_jobstats() {
14753         local cmd=($1)
14754         shift
14755         local facets="$@"
14756
14757 # we don't really need to clear the stats for this test to work, since each
14758 # command has a unique jobid, but it makes debugging easier if needed.
14759 #       for facet in $facets; do
14760 #               local dev=$(convert_facet2label $facet)
14761 #               # clear old jobstats
14762 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14763 #       done
14764
14765         # use a new JobID for each test, or we might see an old one
14766         [ "$JOBENV" = "FAKE_JOBID" ] &&
14767                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14768
14769         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14770
14771         [ "$JOBENV" = "nodelocal" ] && {
14772                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14773                 $LCTL set_param jobid_name=$FAKE_JOBID
14774                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14775         }
14776
14777         log "Test: ${cmd[*]}"
14778         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14779
14780         if [ $JOBENV = "FAKE_JOBID" ]; then
14781                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14782         else
14783                 ${cmd[*]}
14784         fi
14785
14786         # all files are created on OST0000
14787         for facet in $facets; do
14788                 local stats="*.$(convert_facet2label $facet).job_stats"
14789
14790                 # strip out libtool wrappers for in-tree executables
14791                 if [ $(do_facet $facet lctl get_param $stats |
14792                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14793                         do_facet $facet lctl get_param $stats
14794                         error "No jobstats for $JOBVAL found on $facet::$stats"
14795                 fi
14796         done
14797 }
14798
14799 jobstats_set() {
14800         local new_jobenv=$1
14801
14802         set_persistent_param_and_check client "jobid_var" \
14803                 "$FSNAME.sys.jobid_var" $new_jobenv
14804 }
14805
14806 test_205() { # Job stats
14807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14808         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14809                 skip "Need MDS version with at least 2.7.1"
14810         remote_mgs_nodsh && skip "remote MGS with nodsh"
14811         remote_mds_nodsh && skip "remote MDS with nodsh"
14812         remote_ost_nodsh && skip "remote OST with nodsh"
14813         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14814                 skip "Server doesn't support jobstats"
14815         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14816
14817         local old_jobenv=$($LCTL get_param -n jobid_var)
14818         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14819
14820         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14821                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14822         else
14823                 stack_trap "do_facet mgs $PERM_CMD \
14824                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14825         fi
14826         changelog_register
14827
14828         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14829                                 mdt.*.job_cleanup_interval | head -n 1)
14830         local new_interval=5
14831         do_facet $SINGLEMDS \
14832                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14833         stack_trap "do_facet $SINGLEMDS \
14834                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14835         local start=$SECONDS
14836
14837         local cmd
14838         # mkdir
14839         cmd="mkdir $DIR/$tdir"
14840         verify_jobstats "$cmd" "$SINGLEMDS"
14841         # rmdir
14842         cmd="rmdir $DIR/$tdir"
14843         verify_jobstats "$cmd" "$SINGLEMDS"
14844         # mkdir on secondary MDT
14845         if [ $MDSCOUNT -gt 1 ]; then
14846                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14847                 verify_jobstats "$cmd" "mds2"
14848         fi
14849         # mknod
14850         cmd="mknod $DIR/$tfile c 1 3"
14851         verify_jobstats "$cmd" "$SINGLEMDS"
14852         # unlink
14853         cmd="rm -f $DIR/$tfile"
14854         verify_jobstats "$cmd" "$SINGLEMDS"
14855         # create all files on OST0000 so verify_jobstats can find OST stats
14856         # open & close
14857         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14858         verify_jobstats "$cmd" "$SINGLEMDS"
14859         # setattr
14860         cmd="touch $DIR/$tfile"
14861         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14862         # write
14863         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14864         verify_jobstats "$cmd" "ost1"
14865         # read
14866         cancel_lru_locks osc
14867         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14868         verify_jobstats "$cmd" "ost1"
14869         # truncate
14870         cmd="$TRUNCATE $DIR/$tfile 0"
14871         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14872         # rename
14873         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14874         verify_jobstats "$cmd" "$SINGLEMDS"
14875         # jobstats expiry - sleep until old stats should be expired
14876         local left=$((new_interval + 5 - (SECONDS - start)))
14877         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14878                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14879                         "0" $left
14880         cmd="mkdir $DIR/$tdir.expire"
14881         verify_jobstats "$cmd" "$SINGLEMDS"
14882         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14883             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14884
14885         # Ensure that jobid are present in changelog (if supported by MDS)
14886         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14887                 changelog_dump | tail -10
14888                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14889                 [ $jobids -eq 9 ] ||
14890                         error "Wrong changelog jobid count $jobids != 9"
14891
14892                 # LU-5862
14893                 JOBENV="disable"
14894                 jobstats_set $JOBENV
14895                 touch $DIR/$tfile
14896                 changelog_dump | grep $tfile
14897                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14898                 [ $jobids -eq 0 ] ||
14899                         error "Unexpected jobids when jobid_var=$JOBENV"
14900         fi
14901
14902         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14903         JOBENV="JOBCOMPLEX"
14904         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14905
14906         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14907 }
14908 run_test 205 "Verify job stats"
14909
14910 # LU-1480, LU-1773 and LU-1657
14911 test_206() {
14912         mkdir -p $DIR/$tdir
14913         $LFS setstripe -c -1 $DIR/$tdir
14914 #define OBD_FAIL_LOV_INIT 0x1403
14915         $LCTL set_param fail_loc=0xa0001403
14916         $LCTL set_param fail_val=1
14917         touch $DIR/$tdir/$tfile || true
14918 }
14919 run_test 206 "fail lov_init_raid0() doesn't lbug"
14920
14921 test_207a() {
14922         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14923         local fsz=`stat -c %s $DIR/$tfile`
14924         cancel_lru_locks mdc
14925
14926         # do not return layout in getattr intent
14927 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14928         $LCTL set_param fail_loc=0x170
14929         local sz=`stat -c %s $DIR/$tfile`
14930
14931         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14932
14933         rm -rf $DIR/$tfile
14934 }
14935 run_test 207a "can refresh layout at glimpse"
14936
14937 test_207b() {
14938         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14939         local cksum=`md5sum $DIR/$tfile`
14940         local fsz=`stat -c %s $DIR/$tfile`
14941         cancel_lru_locks mdc
14942         cancel_lru_locks osc
14943
14944         # do not return layout in getattr intent
14945 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14946         $LCTL set_param fail_loc=0x171
14947
14948         # it will refresh layout after the file is opened but before read issues
14949         echo checksum is "$cksum"
14950         echo "$cksum" |md5sum -c --quiet || error "file differs"
14951
14952         rm -rf $DIR/$tfile
14953 }
14954 run_test 207b "can refresh layout at open"
14955
14956 test_208() {
14957         # FIXME: in this test suite, only RD lease is used. This is okay
14958         # for now as only exclusive open is supported. After generic lease
14959         # is done, this test suite should be revised. - Jinshan
14960
14961         remote_mds_nodsh && skip "remote MDS with nodsh"
14962         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14963                 skip "Need MDS version at least 2.4.52"
14964
14965         echo "==== test 1: verify get lease work"
14966         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14967
14968         echo "==== test 2: verify lease can be broken by upcoming open"
14969         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14970         local PID=$!
14971         sleep 1
14972
14973         $MULTIOP $DIR/$tfile oO_RDONLY:c
14974         kill -USR1 $PID && wait $PID || error "break lease error"
14975
14976         echo "==== test 3: verify lease can't be granted if an open already exists"
14977         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14978         local PID=$!
14979         sleep 1
14980
14981         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14982         kill -USR1 $PID && wait $PID || error "open file error"
14983
14984         echo "==== test 4: lease can sustain over recovery"
14985         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14986         PID=$!
14987         sleep 1
14988
14989         fail mds1
14990
14991         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14992
14993         echo "==== test 5: lease broken can't be regained by replay"
14994         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14995         PID=$!
14996         sleep 1
14997
14998         # open file to break lease and then recovery
14999         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15000         fail mds1
15001
15002         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15003
15004         rm -f $DIR/$tfile
15005 }
15006 run_test 208 "Exclusive open"
15007
15008 test_209() {
15009         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15010                 skip_env "must have disp_stripe"
15011
15012         touch $DIR/$tfile
15013         sync; sleep 5; sync;
15014
15015         echo 3 > /proc/sys/vm/drop_caches
15016         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15017
15018         # open/close 500 times
15019         for i in $(seq 500); do
15020                 cat $DIR/$tfile
15021         done
15022
15023         echo 3 > /proc/sys/vm/drop_caches
15024         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15025
15026         echo "before: $req_before, after: $req_after"
15027         [ $((req_after - req_before)) -ge 300 ] &&
15028                 error "open/close requests are not freed"
15029         return 0
15030 }
15031 run_test 209 "read-only open/close requests should be freed promptly"
15032
15033 test_212() {
15034         size=`date +%s`
15035         size=$((size % 8192 + 1))
15036         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15037         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15038         rm -f $DIR/f212 $DIR/f212.xyz
15039 }
15040 run_test 212 "Sendfile test ============================================"
15041
15042 test_213() {
15043         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15044         cancel_lru_locks osc
15045         lctl set_param fail_loc=0x8000040f
15046         # generate a read lock
15047         cat $DIR/$tfile > /dev/null
15048         # write to the file, it will try to cancel the above read lock.
15049         cat /etc/hosts >> $DIR/$tfile
15050 }
15051 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15052
15053 test_214() { # for bug 20133
15054         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15055         for (( i=0; i < 340; i++ )) ; do
15056                 touch $DIR/$tdir/d214c/a$i
15057         done
15058
15059         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15060         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15061         ls $DIR/d214c || error "ls $DIR/d214c failed"
15062         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15063         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15064 }
15065 run_test 214 "hash-indexed directory test - bug 20133"
15066
15067 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15068 create_lnet_proc_files() {
15069         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15070 }
15071
15072 # counterpart of create_lnet_proc_files
15073 remove_lnet_proc_files() {
15074         rm -f $TMP/lnet_$1.sys
15075 }
15076
15077 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15078 # 3rd arg as regexp for body
15079 check_lnet_proc_stats() {
15080         local l=$(cat "$TMP/lnet_$1" |wc -l)
15081         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15082
15083         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15084 }
15085
15086 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15087 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15088 # optional and can be regexp for 2nd line (lnet.routes case)
15089 check_lnet_proc_entry() {
15090         local blp=2          # blp stands for 'position of 1st line of body'
15091         [ -z "$5" ] || blp=3 # lnet.routes case
15092
15093         local l=$(cat "$TMP/lnet_$1" |wc -l)
15094         # subtracting one from $blp because the body can be empty
15095         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15096
15097         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15098                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15099
15100         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15101                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15102
15103         # bail out if any unexpected line happened
15104         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15105         [ "$?" != 0 ] || error "$2 misformatted"
15106 }
15107
15108 test_215() { # for bugs 18102, 21079, 21517
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110
15111         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15112         local P='[1-9][0-9]*'           # positive numeric
15113         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15114         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15115         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15116         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15117
15118         local L1 # regexp for 1st line
15119         local L2 # regexp for 2nd line (optional)
15120         local BR # regexp for the rest (body)
15121
15122         # lnet.stats should look as 11 space-separated non-negative numerics
15123         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15124         create_lnet_proc_files "stats"
15125         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15126         remove_lnet_proc_files "stats"
15127
15128         # lnet.routes should look like this:
15129         # Routing disabled/enabled
15130         # net hops priority state router
15131         # where net is a string like tcp0, hops > 0, priority >= 0,
15132         # state is up/down,
15133         # router is a string like 192.168.1.1@tcp2
15134         L1="^Routing (disabled|enabled)$"
15135         L2="^net +hops +priority +state +router$"
15136         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15137         create_lnet_proc_files "routes"
15138         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15139         remove_lnet_proc_files "routes"
15140
15141         # lnet.routers should look like this:
15142         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15143         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15144         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15145         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15146         L1="^ref +rtr_ref +alive +router$"
15147         BR="^$P +$P +(up|down) +$NID$"
15148         create_lnet_proc_files "routers"
15149         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15150         remove_lnet_proc_files "routers"
15151
15152         # lnet.peers should look like this:
15153         # nid refs state last max rtr min tx min queue
15154         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15155         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15156         # numeric (0 or >0 or <0), queue >= 0.
15157         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15158         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15159         create_lnet_proc_files "peers"
15160         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15161         remove_lnet_proc_files "peers"
15162
15163         # lnet.buffers  should look like this:
15164         # pages count credits min
15165         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15166         L1="^pages +count +credits +min$"
15167         BR="^ +$N +$N +$I +$I$"
15168         create_lnet_proc_files "buffers"
15169         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15170         remove_lnet_proc_files "buffers"
15171
15172         # lnet.nis should look like this:
15173         # nid status alive refs peer rtr max tx min
15174         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15175         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15176         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15177         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15178         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15179         create_lnet_proc_files "nis"
15180         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15181         remove_lnet_proc_files "nis"
15182
15183         # can we successfully write to lnet.stats?
15184         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15185 }
15186 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15187
15188 test_216() { # bug 20317
15189         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15190         remote_ost_nodsh && skip "remote OST with nodsh"
15191
15192         local node
15193         local facets=$(get_facets OST)
15194         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15195
15196         save_lustre_params client "osc.*.contention_seconds" > $p
15197         save_lustre_params $facets \
15198                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15199         save_lustre_params $facets \
15200                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15201         save_lustre_params $facets \
15202                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15203         clear_stats osc.*.osc_stats
15204
15205         # agressive lockless i/o settings
15206         do_nodes $(comma_list $(osts_nodes)) \
15207                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15208                         ldlm.namespaces.filter-*.contended_locks=0 \
15209                         ldlm.namespaces.filter-*.contention_seconds=60"
15210         lctl set_param -n osc.*.contention_seconds=60
15211
15212         $DIRECTIO write $DIR/$tfile 0 10 4096
15213         $CHECKSTAT -s 40960 $DIR/$tfile
15214
15215         # disable lockless i/o
15216         do_nodes $(comma_list $(osts_nodes)) \
15217                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15218                         ldlm.namespaces.filter-*.contended_locks=32 \
15219                         ldlm.namespaces.filter-*.contention_seconds=0"
15220         lctl set_param -n osc.*.contention_seconds=0
15221         clear_stats osc.*.osc_stats
15222
15223         dd if=/dev/zero of=$DIR/$tfile count=0
15224         $CHECKSTAT -s 0 $DIR/$tfile
15225
15226         restore_lustre_params <$p
15227         rm -f $p
15228         rm $DIR/$tfile
15229 }
15230 run_test 216 "check lockless direct write updates file size and kms correctly"
15231
15232 test_217() { # bug 22430
15233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15234
15235         local node
15236         local nid
15237
15238         for node in $(nodes_list); do
15239                 nid=$(host_nids_address $node $NETTYPE)
15240                 if [[ $nid = *-* ]] ; then
15241                         echo "lctl ping $(h2nettype $nid)"
15242                         lctl ping $(h2nettype $nid)
15243                 else
15244                         echo "skipping $node (no hyphen detected)"
15245                 fi
15246         done
15247 }
15248 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15249
15250 test_218() {
15251        # do directio so as not to populate the page cache
15252        log "creating a 10 Mb file"
15253        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15254        log "starting reads"
15255        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15256        log "truncating the file"
15257        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15258        log "killing dd"
15259        kill %+ || true # reads might have finished
15260        echo "wait until dd is finished"
15261        wait
15262        log "removing the temporary file"
15263        rm -rf $DIR/$tfile || error "tmp file removal failed"
15264 }
15265 run_test 218 "parallel read and truncate should not deadlock"
15266
15267 test_219() {
15268         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15269
15270         # write one partial page
15271         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15272         # set no grant so vvp_io_commit_write will do sync write
15273         $LCTL set_param fail_loc=0x411
15274         # write a full page at the end of file
15275         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15276
15277         $LCTL set_param fail_loc=0
15278         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15279         $LCTL set_param fail_loc=0x411
15280         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15281
15282         # LU-4201
15283         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15284         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15285 }
15286 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15287
15288 test_220() { #LU-325
15289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15290         remote_ost_nodsh && skip "remote OST with nodsh"
15291         remote_mds_nodsh && skip "remote MDS with nodsh"
15292         remote_mgs_nodsh && skip "remote MGS with nodsh"
15293
15294         local OSTIDX=0
15295
15296         # create on MDT0000 so the last_id and next_id are correct
15297         mkdir $DIR/$tdir
15298         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15299         OST=${OST%_UUID}
15300
15301         # on the mdt's osc
15302         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15303         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15304                         osp.$mdtosc_proc1.prealloc_last_id)
15305         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15306                         osp.$mdtosc_proc1.prealloc_next_id)
15307
15308         $LFS df -i
15309
15310         if ! combined_mgs_mds ; then
15311                 mount_mgs_client
15312         fi
15313
15314         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15315         #define OBD_FAIL_OST_ENOINO              0x229
15316         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15317         create_pool $FSNAME.$TESTNAME || return 1
15318         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15319
15320         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15321
15322         MDSOBJS=$((last_id - next_id))
15323         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15324
15325         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15326         echo "OST still has $count kbytes free"
15327
15328         echo "create $MDSOBJS files @next_id..."
15329         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15330
15331         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15332                         osp.$mdtosc_proc1.prealloc_last_id)
15333         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15334                         osp.$mdtosc_proc1.prealloc_next_id)
15335
15336         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15337         $LFS df -i
15338
15339         echo "cleanup..."
15340
15341         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15342         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15343
15344         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15345                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15346         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15347                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15348         echo "unlink $MDSOBJS files @$next_id..."
15349         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15350
15351         if ! combined_mgs_mds ; then
15352                 umount_mgs_client
15353         fi
15354 }
15355 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15356
15357 test_221() {
15358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15359
15360         dd if=`which date` of=$MOUNT/date oflag=sync
15361         chmod +x $MOUNT/date
15362
15363         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15364         $LCTL set_param fail_loc=0x80001401
15365
15366         $MOUNT/date > /dev/null
15367         rm -f $MOUNT/date
15368 }
15369 run_test 221 "make sure fault and truncate race to not cause OOM"
15370
15371 test_222a () {
15372         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15373
15374         rm -rf $DIR/$tdir
15375         test_mkdir $DIR/$tdir
15376         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15377         createmany -o $DIR/$tdir/$tfile 10
15378         cancel_lru_locks mdc
15379         cancel_lru_locks osc
15380         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15381         $LCTL set_param fail_loc=0x31a
15382         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15383         $LCTL set_param fail_loc=0
15384         rm -r $DIR/$tdir
15385 }
15386 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15387
15388 test_222b () {
15389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15390
15391         rm -rf $DIR/$tdir
15392         test_mkdir $DIR/$tdir
15393         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15394         createmany -o $DIR/$tdir/$tfile 10
15395         cancel_lru_locks mdc
15396         cancel_lru_locks osc
15397         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15398         $LCTL set_param fail_loc=0x31a
15399         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15400         $LCTL set_param fail_loc=0
15401 }
15402 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15403
15404 test_223 () {
15405         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15406
15407         rm -rf $DIR/$tdir
15408         test_mkdir $DIR/$tdir
15409         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15410         createmany -o $DIR/$tdir/$tfile 10
15411         cancel_lru_locks mdc
15412         cancel_lru_locks osc
15413         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15414         $LCTL set_param fail_loc=0x31b
15415         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15416         $LCTL set_param fail_loc=0
15417         rm -r $DIR/$tdir
15418 }
15419 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15420
15421 test_224a() { # LU-1039, MRP-303
15422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15423
15424         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15425         $LCTL set_param fail_loc=0x508
15426         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15427         $LCTL set_param fail_loc=0
15428         df $DIR
15429 }
15430 run_test 224a "Don't panic on bulk IO failure"
15431
15432 test_224b() { # LU-1039, MRP-303
15433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15434
15435         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15436         cancel_lru_locks osc
15437         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15438         $LCTL set_param fail_loc=0x515
15439         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15440         $LCTL set_param fail_loc=0
15441         df $DIR
15442 }
15443 run_test 224b "Don't panic on bulk IO failure"
15444
15445 test_224c() { # LU-6441
15446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15447         remote_mds_nodsh && skip "remote MDS with nodsh"
15448
15449         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15450         save_writethrough $p
15451         set_cache writethrough on
15452
15453         local pages_per_rpc=$($LCTL get_param \
15454                                 osc.*.max_pages_per_rpc)
15455         local at_max=$($LCTL get_param -n at_max)
15456         local timeout=$($LCTL get_param -n timeout)
15457         local test_at="at_max"
15458         local param_at="$FSNAME.sys.at_max"
15459         local test_timeout="timeout"
15460         local param_timeout="$FSNAME.sys.timeout"
15461
15462         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15463
15464         set_persistent_param_and_check client "$test_at" "$param_at" 0
15465         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15466
15467         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15468         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15469         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15470         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15471         sync
15472         do_facet ost1 "$LCTL set_param fail_loc=0"
15473
15474         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15475         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15476                 $timeout
15477
15478         $LCTL set_param -n $pages_per_rpc
15479         restore_lustre_params < $p
15480         rm -f $p
15481 }
15482 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15483
15484 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15485 test_225a () {
15486         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15487         if [ -z ${MDSSURVEY} ]; then
15488                 skip_env "mds-survey not found"
15489         fi
15490         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15491                 skip "Need MDS version at least 2.2.51"
15492
15493         local mds=$(facet_host $SINGLEMDS)
15494         local target=$(do_nodes $mds 'lctl dl' |
15495                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15496
15497         local cmd1="file_count=1000 thrhi=4"
15498         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15499         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15500         local cmd="$cmd1 $cmd2 $cmd3"
15501
15502         rm -f ${TMP}/mds_survey*
15503         echo + $cmd
15504         eval $cmd || error "mds-survey with zero-stripe failed"
15505         cat ${TMP}/mds_survey*
15506         rm -f ${TMP}/mds_survey*
15507 }
15508 run_test 225a "Metadata survey sanity with zero-stripe"
15509
15510 test_225b () {
15511         if [ -z ${MDSSURVEY} ]; then
15512                 skip_env "mds-survey not found"
15513         fi
15514         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15515                 skip "Need MDS version at least 2.2.51"
15516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15517         remote_mds_nodsh && skip "remote MDS with nodsh"
15518         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15519                 skip_env "Need to mount OST to test"
15520         fi
15521
15522         local mds=$(facet_host $SINGLEMDS)
15523         local target=$(do_nodes $mds 'lctl dl' |
15524                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15525
15526         local cmd1="file_count=1000 thrhi=4"
15527         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15528         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15529         local cmd="$cmd1 $cmd2 $cmd3"
15530
15531         rm -f ${TMP}/mds_survey*
15532         echo + $cmd
15533         eval $cmd || error "mds-survey with stripe_count failed"
15534         cat ${TMP}/mds_survey*
15535         rm -f ${TMP}/mds_survey*
15536 }
15537 run_test 225b "Metadata survey sanity with stripe_count = 1"
15538
15539 mcreate_path2fid () {
15540         local mode=$1
15541         local major=$2
15542         local minor=$3
15543         local name=$4
15544         local desc=$5
15545         local path=$DIR/$tdir/$name
15546         local fid
15547         local rc
15548         local fid_path
15549
15550         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15551                 error "cannot create $desc"
15552
15553         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15554         rc=$?
15555         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15556
15557         fid_path=$($LFS fid2path $MOUNT $fid)
15558         rc=$?
15559         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15560
15561         [ "$path" == "$fid_path" ] ||
15562                 error "fid2path returned $fid_path, expected $path"
15563
15564         echo "pass with $path and $fid"
15565 }
15566
15567 test_226a () {
15568         rm -rf $DIR/$tdir
15569         mkdir -p $DIR/$tdir
15570
15571         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15572         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15573         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15574         mcreate_path2fid 0040666 0 0 dir "directory"
15575         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15576         mcreate_path2fid 0100666 0 0 file "regular file"
15577         mcreate_path2fid 0120666 0 0 link "symbolic link"
15578         mcreate_path2fid 0140666 0 0 sock "socket"
15579 }
15580 run_test 226a "call path2fid and fid2path on files of all type"
15581
15582 test_226b () {
15583         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15584
15585         local MDTIDX=1
15586
15587         rm -rf $DIR/$tdir
15588         mkdir -p $DIR/$tdir
15589         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15590                 error "create remote directory failed"
15591         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15592         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15593                                 "character special file (null)"
15594         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15595                                 "character special file (no device)"
15596         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15597         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15598                                 "block special file (loop)"
15599         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15600         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15601         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15602 }
15603 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15604
15605 # LU-1299 Executing or running ldd on a truncated executable does not
15606 # cause an out-of-memory condition.
15607 test_227() {
15608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15609         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15610
15611         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15612         chmod +x $MOUNT/date
15613
15614         $MOUNT/date > /dev/null
15615         ldd $MOUNT/date > /dev/null
15616         rm -f $MOUNT/date
15617 }
15618 run_test 227 "running truncated executable does not cause OOM"
15619
15620 # LU-1512 try to reuse idle OI blocks
15621 test_228a() {
15622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15623         remote_mds_nodsh && skip "remote MDS with nodsh"
15624         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15625
15626         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15627         local myDIR=$DIR/$tdir
15628
15629         mkdir -p $myDIR
15630         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15631         $LCTL set_param fail_loc=0x80001002
15632         createmany -o $myDIR/t- 10000
15633         $LCTL set_param fail_loc=0
15634         # The guard is current the largest FID holder
15635         touch $myDIR/guard
15636         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15637                     tr -d '[')
15638         local IDX=$(($SEQ % 64))
15639
15640         do_facet $SINGLEMDS sync
15641         # Make sure journal flushed.
15642         sleep 6
15643         local blk1=$(do_facet $SINGLEMDS \
15644                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15645                      grep Blockcount | awk '{print $4}')
15646
15647         # Remove old files, some OI blocks will become idle.
15648         unlinkmany $myDIR/t- 10000
15649         # Create new files, idle OI blocks should be reused.
15650         createmany -o $myDIR/t- 2000
15651         do_facet $SINGLEMDS sync
15652         # Make sure journal flushed.
15653         sleep 6
15654         local blk2=$(do_facet $SINGLEMDS \
15655                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15656                      grep Blockcount | awk '{print $4}')
15657
15658         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15659 }
15660 run_test 228a "try to reuse idle OI blocks"
15661
15662 test_228b() {
15663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15664         remote_mds_nodsh && skip "remote MDS with nodsh"
15665         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15666
15667         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15668         local myDIR=$DIR/$tdir
15669
15670         mkdir -p $myDIR
15671         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15672         $LCTL set_param fail_loc=0x80001002
15673         createmany -o $myDIR/t- 10000
15674         $LCTL set_param fail_loc=0
15675         # The guard is current the largest FID holder
15676         touch $myDIR/guard
15677         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15678                     tr -d '[')
15679         local IDX=$(($SEQ % 64))
15680
15681         do_facet $SINGLEMDS sync
15682         # Make sure journal flushed.
15683         sleep 6
15684         local blk1=$(do_facet $SINGLEMDS \
15685                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15686                      grep Blockcount | awk '{print $4}')
15687
15688         # Remove old files, some OI blocks will become idle.
15689         unlinkmany $myDIR/t- 10000
15690
15691         # stop the MDT
15692         stop $SINGLEMDS || error "Fail to stop MDT."
15693         # remount the MDT
15694         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15695
15696         df $MOUNT || error "Fail to df."
15697         # Create new files, idle OI blocks should be reused.
15698         createmany -o $myDIR/t- 2000
15699         do_facet $SINGLEMDS sync
15700         # Make sure journal flushed.
15701         sleep 6
15702         local blk2=$(do_facet $SINGLEMDS \
15703                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15704                      grep Blockcount | awk '{print $4}')
15705
15706         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15707 }
15708 run_test 228b "idle OI blocks can be reused after MDT restart"
15709
15710 #LU-1881
15711 test_228c() {
15712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15713         remote_mds_nodsh && skip "remote MDS with nodsh"
15714         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15715
15716         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15717         local myDIR=$DIR/$tdir
15718
15719         mkdir -p $myDIR
15720         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15721         $LCTL set_param fail_loc=0x80001002
15722         # 20000 files can guarantee there are index nodes in the OI file
15723         createmany -o $myDIR/t- 20000
15724         $LCTL set_param fail_loc=0
15725         # The guard is current the largest FID holder
15726         touch $myDIR/guard
15727         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15728                     tr -d '[')
15729         local IDX=$(($SEQ % 64))
15730
15731         do_facet $SINGLEMDS sync
15732         # Make sure journal flushed.
15733         sleep 6
15734         local blk1=$(do_facet $SINGLEMDS \
15735                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15736                      grep Blockcount | awk '{print $4}')
15737
15738         # Remove old files, some OI blocks will become idle.
15739         unlinkmany $myDIR/t- 20000
15740         rm -f $myDIR/guard
15741         # The OI file should become empty now
15742
15743         # Create new files, idle OI blocks should be reused.
15744         createmany -o $myDIR/t- 2000
15745         do_facet $SINGLEMDS sync
15746         # Make sure journal flushed.
15747         sleep 6
15748         local blk2=$(do_facet $SINGLEMDS \
15749                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15750                      grep Blockcount | awk '{print $4}')
15751
15752         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15753 }
15754 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15755
15756 test_229() { # LU-2482, LU-3448
15757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15758         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15759         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15760                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15761
15762         rm -f $DIR/$tfile
15763
15764         # Create a file with a released layout and stripe count 2.
15765         $MULTIOP $DIR/$tfile H2c ||
15766                 error "failed to create file with released layout"
15767
15768         $LFS getstripe -v $DIR/$tfile
15769
15770         local pattern=$($LFS getstripe -L $DIR/$tfile)
15771         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15772
15773         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15774                 error "getstripe"
15775         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15776         stat $DIR/$tfile || error "failed to stat released file"
15777
15778         chown $RUNAS_ID $DIR/$tfile ||
15779                 error "chown $RUNAS_ID $DIR/$tfile failed"
15780
15781         chgrp $RUNAS_ID $DIR/$tfile ||
15782                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15783
15784         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15785         rm $DIR/$tfile || error "failed to remove released file"
15786 }
15787 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15788
15789 test_230a() {
15790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15791         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15792         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15793                 skip "Need MDS version at least 2.11.52"
15794
15795         local MDTIDX=1
15796
15797         test_mkdir $DIR/$tdir
15798         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15799         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15800         [ $mdt_idx -ne 0 ] &&
15801                 error "create local directory on wrong MDT $mdt_idx"
15802
15803         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15804                         error "create remote directory failed"
15805         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15806         [ $mdt_idx -ne $MDTIDX ] &&
15807                 error "create remote directory on wrong MDT $mdt_idx"
15808
15809         createmany -o $DIR/$tdir/test_230/t- 10 ||
15810                 error "create files on remote directory failed"
15811         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15812         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15813         rm -r $DIR/$tdir || error "unlink remote directory failed"
15814 }
15815 run_test 230a "Create remote directory and files under the remote directory"
15816
15817 test_230b() {
15818         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15819         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15820         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15821                 skip "Need MDS version at least 2.11.52"
15822
15823         local MDTIDX=1
15824         local mdt_index
15825         local i
15826         local file
15827         local pid
15828         local stripe_count
15829         local migrate_dir=$DIR/$tdir/migrate_dir
15830         local other_dir=$DIR/$tdir/other_dir
15831
15832         test_mkdir $DIR/$tdir
15833         test_mkdir -i0 -c1 $migrate_dir
15834         test_mkdir -i0 -c1 $other_dir
15835         for ((i=0; i<10; i++)); do
15836                 mkdir -p $migrate_dir/dir_${i}
15837                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15838                         error "create files under remote dir failed $i"
15839         done
15840
15841         cp /etc/passwd $migrate_dir/$tfile
15842         cp /etc/passwd $other_dir/$tfile
15843         chattr +SAD $migrate_dir
15844         chattr +SAD $migrate_dir/$tfile
15845
15846         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15847         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15848         local old_dir_mode=$(stat -c%f $migrate_dir)
15849         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15850
15851         mkdir -p $migrate_dir/dir_default_stripe2
15852         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15853         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15854
15855         mkdir -p $other_dir
15856         ln $migrate_dir/$tfile $other_dir/luna
15857         ln $migrate_dir/$tfile $migrate_dir/sofia
15858         ln $other_dir/$tfile $migrate_dir/david
15859         ln -s $migrate_dir/$tfile $other_dir/zachary
15860         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15861         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15862
15863         $LFS migrate -m $MDTIDX $migrate_dir ||
15864                 error "fails on migrating remote dir to MDT1"
15865
15866         echo "migratate to MDT1, then checking.."
15867         for ((i = 0; i < 10; i++)); do
15868                 for file in $(find $migrate_dir/dir_${i}); do
15869                         mdt_index=$($LFS getstripe -m $file)
15870                         [ $mdt_index == $MDTIDX ] ||
15871                                 error "$file is not on MDT${MDTIDX}"
15872                 done
15873         done
15874
15875         # the multiple link file should still in MDT0
15876         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15877         [ $mdt_index == 0 ] ||
15878                 error "$file is not on MDT${MDTIDX}"
15879
15880         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15881         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15882                 error " expect $old_dir_flag get $new_dir_flag"
15883
15884         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15885         [ "$old_file_flag" = "$new_file_flag" ] ||
15886                 error " expect $old_file_flag get $new_file_flag"
15887
15888         local new_dir_mode=$(stat -c%f $migrate_dir)
15889         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15890                 error "expect mode $old_dir_mode get $new_dir_mode"
15891
15892         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15893         [ "$old_file_mode" = "$new_file_mode" ] ||
15894                 error "expect mode $old_file_mode get $new_file_mode"
15895
15896         diff /etc/passwd $migrate_dir/$tfile ||
15897                 error "$tfile different after migration"
15898
15899         diff /etc/passwd $other_dir/luna ||
15900                 error "luna different after migration"
15901
15902         diff /etc/passwd $migrate_dir/sofia ||
15903                 error "sofia different after migration"
15904
15905         diff /etc/passwd $migrate_dir/david ||
15906                 error "david different after migration"
15907
15908         diff /etc/passwd $other_dir/zachary ||
15909                 error "zachary different after migration"
15910
15911         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15912                 error "${tfile}_ln different after migration"
15913
15914         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15915                 error "${tfile}_ln_other different after migration"
15916
15917         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15918         [ $stripe_count = 2 ] ||
15919                 error "dir strpe_count $d != 2 after migration."
15920
15921         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15922         [ $stripe_count = 2 ] ||
15923                 error "file strpe_count $d != 2 after migration."
15924
15925         #migrate back to MDT0
15926         MDTIDX=0
15927
15928         $LFS migrate -m $MDTIDX $migrate_dir ||
15929                 error "fails on migrating remote dir to MDT0"
15930
15931         echo "migrate back to MDT0, checking.."
15932         for file in $(find $migrate_dir); do
15933                 mdt_index=$($LFS getstripe -m $file)
15934                 [ $mdt_index == $MDTIDX ] ||
15935                         error "$file is not on MDT${MDTIDX}"
15936         done
15937
15938         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15939         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15940                 error " expect $old_dir_flag get $new_dir_flag"
15941
15942         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15943         [ "$old_file_flag" = "$new_file_flag" ] ||
15944                 error " expect $old_file_flag get $new_file_flag"
15945
15946         local new_dir_mode=$(stat -c%f $migrate_dir)
15947         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15948                 error "expect mode $old_dir_mode get $new_dir_mode"
15949
15950         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15951         [ "$old_file_mode" = "$new_file_mode" ] ||
15952                 error "expect mode $old_file_mode get $new_file_mode"
15953
15954         diff /etc/passwd ${migrate_dir}/$tfile ||
15955                 error "$tfile different after migration"
15956
15957         diff /etc/passwd ${other_dir}/luna ||
15958                 error "luna different after migration"
15959
15960         diff /etc/passwd ${migrate_dir}/sofia ||
15961                 error "sofia different after migration"
15962
15963         diff /etc/passwd ${other_dir}/zachary ||
15964                 error "zachary different after migration"
15965
15966         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15967                 error "${tfile}_ln different after migration"
15968
15969         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15970                 error "${tfile}_ln_other different after migration"
15971
15972         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15973         [ $stripe_count = 2 ] ||
15974                 error "dir strpe_count $d != 2 after migration."
15975
15976         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15977         [ $stripe_count = 2 ] ||
15978                 error "file strpe_count $d != 2 after migration."
15979
15980         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15981 }
15982 run_test 230b "migrate directory"
15983
15984 test_230c() {
15985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15986         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15987         remote_mds_nodsh && skip "remote MDS with nodsh"
15988         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15989                 skip "Need MDS version at least 2.11.52"
15990
15991         local MDTIDX=1
15992         local total=3
15993         local mdt_index
15994         local file
15995         local migrate_dir=$DIR/$tdir/migrate_dir
15996
15997         #If migrating directory fails in the middle, all entries of
15998         #the directory is still accessiable.
15999         test_mkdir $DIR/$tdir
16000         test_mkdir -i0 -c1 $migrate_dir
16001         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16002         stat $migrate_dir
16003         createmany -o $migrate_dir/f $total ||
16004                 error "create files under ${migrate_dir} failed"
16005
16006         # fail after migrating top dir, and this will fail only once, so the
16007         # first sub file migration will fail (currently f3), others succeed.
16008         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16009         do_facet mds1 lctl set_param fail_loc=0x1801
16010         local t=$(ls $migrate_dir | wc -l)
16011         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16012                 error "migrate should fail"
16013         local u=$(ls $migrate_dir | wc -l)
16014         [ "$u" == "$t" ] || error "$u != $t during migration"
16015
16016         # add new dir/file should succeed
16017         mkdir $migrate_dir/dir ||
16018                 error "mkdir failed under migrating directory"
16019         touch $migrate_dir/file ||
16020                 error "create file failed under migrating directory"
16021
16022         # add file with existing name should fail
16023         for file in $migrate_dir/f*; do
16024                 stat $file > /dev/null || error "stat $file failed"
16025                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16026                         error "open(O_CREAT|O_EXCL) $file should fail"
16027                 $MULTIOP $file m && error "create $file should fail"
16028                 touch $DIR/$tdir/remote_dir/$tfile ||
16029                         error "touch $tfile failed"
16030                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16031                         error "link $file should fail"
16032                 mdt_index=$($LFS getstripe -m $file)
16033                 if [ $mdt_index == 0 ]; then
16034                         # file failed to migrate is not allowed to rename to
16035                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16036                                 error "rename to $file should fail"
16037                 else
16038                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16039                                 error "rename to $file failed"
16040                 fi
16041                 echo hello >> $file || error "write $file failed"
16042         done
16043
16044         # resume migration with different options should fail
16045         $LFS migrate -m 0 $migrate_dir &&
16046                 error "migrate -m 0 $migrate_dir should fail"
16047
16048         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16049                 error "migrate -c 2 $migrate_dir should fail"
16050
16051         # resume migration should succeed
16052         $LFS migrate -m $MDTIDX $migrate_dir ||
16053                 error "migrate $migrate_dir failed"
16054
16055         echo "Finish migration, then checking.."
16056         for file in $(find $migrate_dir); do
16057                 mdt_index=$($LFS getstripe -m $file)
16058                 [ $mdt_index == $MDTIDX ] ||
16059                         error "$file is not on MDT${MDTIDX}"
16060         done
16061
16062         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16063 }
16064 run_test 230c "check directory accessiblity if migration failed"
16065
16066 test_230d() {
16067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16068         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16069         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16070                 skip "Need MDS version at least 2.11.52"
16071         # LU-11235
16072         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16073
16074         local migrate_dir=$DIR/$tdir/migrate_dir
16075         local old_index
16076         local new_index
16077         local old_count
16078         local new_count
16079         local new_hash
16080         local mdt_index
16081         local i
16082         local j
16083
16084         old_index=$((RANDOM % MDSCOUNT))
16085         old_count=$((MDSCOUNT - old_index))
16086         new_index=$((RANDOM % MDSCOUNT))
16087         new_count=$((MDSCOUNT - new_index))
16088         new_hash="all_char"
16089
16090         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16091         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16092
16093         test_mkdir $DIR/$tdir
16094         test_mkdir -i $old_index -c $old_count $migrate_dir
16095
16096         for ((i=0; i<100; i++)); do
16097                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16098                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16099                         error "create files under remote dir failed $i"
16100         done
16101
16102         echo -n "Migrate from MDT$old_index "
16103         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16104         echo -n "to MDT$new_index"
16105         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16106         echo
16107
16108         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16109         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16110                 error "migrate remote dir error"
16111
16112         echo "Finish migration, then checking.."
16113         for file in $(find $migrate_dir); do
16114                 mdt_index=$($LFS getstripe -m $file)
16115                 if [ $mdt_index -lt $new_index ] ||
16116                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16117                         error "$file is on MDT$mdt_index"
16118                 fi
16119         done
16120
16121         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16122 }
16123 run_test 230d "check migrate big directory"
16124
16125 test_230e() {
16126         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16127         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16128         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16129                 skip "Need MDS version at least 2.11.52"
16130
16131         local i
16132         local j
16133         local a_fid
16134         local b_fid
16135
16136         mkdir -p $DIR/$tdir
16137         mkdir $DIR/$tdir/migrate_dir
16138         mkdir $DIR/$tdir/other_dir
16139         touch $DIR/$tdir/migrate_dir/a
16140         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16141         ls $DIR/$tdir/other_dir
16142
16143         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16144                 error "migrate dir fails"
16145
16146         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16147         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16148
16149         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16150         [ $mdt_index == 0 ] || error "a is not on MDT0"
16151
16152         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16153                 error "migrate dir fails"
16154
16155         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16156         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16157
16158         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16159         [ $mdt_index == 1 ] || error "a is not on MDT1"
16160
16161         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16162         [ $mdt_index == 1 ] || error "b is not on MDT1"
16163
16164         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16165         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16166
16167         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16168
16169         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16170 }
16171 run_test 230e "migrate mulitple local link files"
16172
16173 test_230f() {
16174         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16175         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16176         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16177                 skip "Need MDS version at least 2.11.52"
16178
16179         local a_fid
16180         local ln_fid
16181
16182         mkdir -p $DIR/$tdir
16183         mkdir $DIR/$tdir/migrate_dir
16184         $LFS mkdir -i1 $DIR/$tdir/other_dir
16185         touch $DIR/$tdir/migrate_dir/a
16186         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16187         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16188         ls $DIR/$tdir/other_dir
16189
16190         # a should be migrated to MDT1, since no other links on MDT0
16191         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16192                 error "#1 migrate dir fails"
16193         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16194         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16195         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16196         [ $mdt_index == 1 ] || error "a is not on MDT1"
16197
16198         # a should stay on MDT1, because it is a mulitple link file
16199         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16200                 error "#2 migrate dir fails"
16201         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16202         [ $mdt_index == 1 ] || error "a is not on MDT1"
16203
16204         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16205                 error "#3 migrate dir fails"
16206
16207         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16208         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16209         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16210
16211         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16212         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16213
16214         # a should be migrated to MDT0, since no other links on MDT1
16215         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16216                 error "#4 migrate dir fails"
16217         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16218         [ $mdt_index == 0 ] || error "a is not on MDT0"
16219
16220         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16221 }
16222 run_test 230f "migrate mulitple remote link files"
16223
16224 test_230g() {
16225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16226         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16227         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16228                 skip "Need MDS version at least 2.11.52"
16229
16230         mkdir -p $DIR/$tdir/migrate_dir
16231
16232         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16233                 error "migrating dir to non-exist MDT succeeds"
16234         true
16235 }
16236 run_test 230g "migrate dir to non-exist MDT"
16237
16238 test_230h() {
16239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16240         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16241         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16242                 skip "Need MDS version at least 2.11.52"
16243
16244         local mdt_index
16245
16246         mkdir -p $DIR/$tdir/migrate_dir
16247
16248         $LFS migrate -m1 $DIR &&
16249                 error "migrating mountpoint1 should fail"
16250
16251         $LFS migrate -m1 $DIR/$tdir/.. &&
16252                 error "migrating mountpoint2 should fail"
16253
16254         # same as mv
16255         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16256                 error "migrating $tdir/migrate_dir/.. should fail"
16257
16258         true
16259 }
16260 run_test 230h "migrate .. and root"
16261
16262 test_230i() {
16263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16264         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16265         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16266                 skip "Need MDS version at least 2.11.52"
16267
16268         mkdir -p $DIR/$tdir/migrate_dir
16269
16270         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16271                 error "migration fails with a tailing slash"
16272
16273         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16274                 error "migration fails with two tailing slashes"
16275 }
16276 run_test 230i "lfs migrate -m tolerates trailing slashes"
16277
16278 test_230j() {
16279         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16280         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16281                 skip "Need MDS version at least 2.11.52"
16282
16283         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16284         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16285                 error "create $tfile failed"
16286         cat /etc/passwd > $DIR/$tdir/$tfile
16287
16288         $LFS migrate -m 1 $DIR/$tdir
16289
16290         cmp /etc/passwd $DIR/$tdir/$tfile ||
16291                 error "DoM file mismatch after migration"
16292 }
16293 run_test 230j "DoM file data not changed after dir migration"
16294
16295 test_230k() {
16296         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16297         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16298                 skip "Need MDS version at least 2.11.56"
16299
16300         local total=20
16301         local files_on_starting_mdt=0
16302
16303         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16304         $LFS getdirstripe $DIR/$tdir
16305         for i in $(seq $total); do
16306                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16307                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16308                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16309         done
16310
16311         echo "$files_on_starting_mdt files on MDT0"
16312
16313         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16314         $LFS getdirstripe $DIR/$tdir
16315
16316         files_on_starting_mdt=0
16317         for i in $(seq $total); do
16318                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16319                         error "file $tfile.$i mismatch after migration"
16320                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16321                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16322         done
16323
16324         echo "$files_on_starting_mdt files on MDT1 after migration"
16325         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16326
16327         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16328         $LFS getdirstripe $DIR/$tdir
16329
16330         files_on_starting_mdt=0
16331         for i in $(seq $total); do
16332                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16333                         error "file $tfile.$i mismatch after 2nd migration"
16334                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16335                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16336         done
16337
16338         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16339         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16340
16341         true
16342 }
16343 run_test 230k "file data not changed after dir migration"
16344
16345 test_230l() {
16346         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16347         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16348                 skip "Need MDS version at least 2.11.56"
16349
16350         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16351         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16352                 error "create files under remote dir failed $i"
16353         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16354 }
16355 run_test 230l "readdir between MDTs won't crash"
16356
16357 test_231a()
16358 {
16359         # For simplicity this test assumes that max_pages_per_rpc
16360         # is the same across all OSCs
16361         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16362         local bulk_size=$((max_pages * PAGE_SIZE))
16363         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16364                                        head -n 1)
16365
16366         mkdir -p $DIR/$tdir
16367         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16368                 error "failed to set stripe with -S ${brw_size}M option"
16369
16370         # clear the OSC stats
16371         $LCTL set_param osc.*.stats=0 &>/dev/null
16372         stop_writeback
16373
16374         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16375         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16376                 oflag=direct &>/dev/null || error "dd failed"
16377
16378         sync; sleep 1; sync # just to be safe
16379         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16380         if [ x$nrpcs != "x1" ]; then
16381                 $LCTL get_param osc.*.stats
16382                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16383         fi
16384
16385         start_writeback
16386         # Drop the OSC cache, otherwise we will read from it
16387         cancel_lru_locks osc
16388
16389         # clear the OSC stats
16390         $LCTL set_param osc.*.stats=0 &>/dev/null
16391
16392         # Client reads $bulk_size.
16393         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16394                 iflag=direct &>/dev/null || error "dd failed"
16395
16396         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16397         if [ x$nrpcs != "x1" ]; then
16398                 $LCTL get_param osc.*.stats
16399                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16400         fi
16401 }
16402 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16403
16404 test_231b() {
16405         mkdir -p $DIR/$tdir
16406         local i
16407         for i in {0..1023}; do
16408                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16409                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16410                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16411         done
16412         sync
16413 }
16414 run_test 231b "must not assert on fully utilized OST request buffer"
16415
16416 test_232a() {
16417         mkdir -p $DIR/$tdir
16418         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16419
16420         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16421         do_facet ost1 $LCTL set_param fail_loc=0x31c
16422
16423         # ignore dd failure
16424         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16425
16426         do_facet ost1 $LCTL set_param fail_loc=0
16427         umount_client $MOUNT || error "umount failed"
16428         mount_client $MOUNT || error "mount failed"
16429         stop ost1 || error "cannot stop ost1"
16430         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16431 }
16432 run_test 232a "failed lock should not block umount"
16433
16434 test_232b() {
16435         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16436                 skip "Need MDS version at least 2.10.58"
16437
16438         mkdir -p $DIR/$tdir
16439         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16440         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16441         sync
16442         cancel_lru_locks osc
16443
16444         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16445         do_facet ost1 $LCTL set_param fail_loc=0x31c
16446
16447         # ignore failure
16448         $LFS data_version $DIR/$tdir/$tfile || true
16449
16450         do_facet ost1 $LCTL set_param fail_loc=0
16451         umount_client $MOUNT || error "umount failed"
16452         mount_client $MOUNT || error "mount failed"
16453         stop ost1 || error "cannot stop ost1"
16454         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16455 }
16456 run_test 232b "failed data version lock should not block umount"
16457
16458 test_233a() {
16459         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16460                 skip "Need MDS version at least 2.3.64"
16461         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16462
16463         local fid=$($LFS path2fid $MOUNT)
16464
16465         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16466                 error "cannot access $MOUNT using its FID '$fid'"
16467 }
16468 run_test 233a "checking that OBF of the FS root succeeds"
16469
16470 test_233b() {
16471         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16472                 skip "Need MDS version at least 2.5.90"
16473         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16474
16475         local fid=$($LFS path2fid $MOUNT/.lustre)
16476
16477         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16478                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16479
16480         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16481         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16482                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16483 }
16484 run_test 233b "checking that OBF of the FS .lustre succeeds"
16485
16486 test_234() {
16487         local p="$TMP/sanityN-$TESTNAME.parameters"
16488         save_lustre_params client "llite.*.xattr_cache" > $p
16489         lctl set_param llite.*.xattr_cache 1 ||
16490                 skip_env "xattr cache is not supported"
16491
16492         mkdir -p $DIR/$tdir || error "mkdir failed"
16493         touch $DIR/$tdir/$tfile || error "touch failed"
16494         # OBD_FAIL_LLITE_XATTR_ENOMEM
16495         $LCTL set_param fail_loc=0x1405
16496         getfattr -n user.attr $DIR/$tdir/$tfile &&
16497                 error "getfattr should have failed with ENOMEM"
16498         $LCTL set_param fail_loc=0x0
16499         rm -rf $DIR/$tdir
16500
16501         restore_lustre_params < $p
16502         rm -f $p
16503 }
16504 run_test 234 "xattr cache should not crash on ENOMEM"
16505
16506 test_235() {
16507         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16508                 skip "Need MDS version at least 2.4.52"
16509
16510         flock_deadlock $DIR/$tfile
16511         local RC=$?
16512         case $RC in
16513                 0)
16514                 ;;
16515                 124) error "process hangs on a deadlock"
16516                 ;;
16517                 *) error "error executing flock_deadlock $DIR/$tfile"
16518                 ;;
16519         esac
16520 }
16521 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16522
16523 #LU-2935
16524 test_236() {
16525         check_swap_layouts_support
16526
16527         local ref1=/etc/passwd
16528         local ref2=/etc/group
16529         local file1=$DIR/$tdir/f1
16530         local file2=$DIR/$tdir/f2
16531
16532         test_mkdir -c1 $DIR/$tdir
16533         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16534         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16535         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16536         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16537         local fd=$(free_fd)
16538         local cmd="exec $fd<>$file2"
16539         eval $cmd
16540         rm $file2
16541         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16542                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16543         cmd="exec $fd>&-"
16544         eval $cmd
16545         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16546
16547         #cleanup
16548         rm -rf $DIR/$tdir
16549 }
16550 run_test 236 "Layout swap on open unlinked file"
16551
16552 # LU-4659 linkea consistency
16553 test_238() {
16554         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16555                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16556                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16557                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16558
16559         touch $DIR/$tfile
16560         ln $DIR/$tfile $DIR/$tfile.lnk
16561         touch $DIR/$tfile.new
16562         mv $DIR/$tfile.new $DIR/$tfile
16563         local fid1=$($LFS path2fid $DIR/$tfile)
16564         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16565         local path1=$($LFS fid2path $FSNAME "$fid1")
16566         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16567         local path2=$($LFS fid2path $FSNAME "$fid2")
16568         [ $tfile.lnk == $path2 ] ||
16569                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16570         rm -f $DIR/$tfile*
16571 }
16572 run_test 238 "Verify linkea consistency"
16573
16574 test_239A() { # was test_239
16575         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16576                 skip "Need MDS version at least 2.5.60"
16577
16578         local list=$(comma_list $(mdts_nodes))
16579
16580         mkdir -p $DIR/$tdir
16581         createmany -o $DIR/$tdir/f- 5000
16582         unlinkmany $DIR/$tdir/f- 5000
16583         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16584                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16585         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16586                         osp.*MDT*.sync_in_flight" | calc_sum)
16587         [ "$changes" -eq 0 ] || error "$changes not synced"
16588 }
16589 run_test 239A "osp_sync test"
16590
16591 test_239a() { #LU-5297
16592         remote_mds_nodsh && skip "remote MDS with nodsh"
16593
16594         touch $DIR/$tfile
16595         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16596         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16597         chgrp $RUNAS_GID $DIR/$tfile
16598         wait_delete_completed
16599 }
16600 run_test 239a "process invalid osp sync record correctly"
16601
16602 test_239b() { #LU-5297
16603         remote_mds_nodsh && skip "remote MDS with nodsh"
16604
16605         touch $DIR/$tfile1
16606         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16607         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16608         chgrp $RUNAS_GID $DIR/$tfile1
16609         wait_delete_completed
16610         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16611         touch $DIR/$tfile2
16612         chgrp $RUNAS_GID $DIR/$tfile2
16613         wait_delete_completed
16614 }
16615 run_test 239b "process osp sync record with ENOMEM error correctly"
16616
16617 test_240() {
16618         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16619         remote_mds_nodsh && skip "remote MDS with nodsh"
16620
16621         mkdir -p $DIR/$tdir
16622
16623         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16624                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16625         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16626                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16627
16628         umount_client $MOUNT || error "umount failed"
16629         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16630         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16631         mount_client $MOUNT || error "failed to mount client"
16632
16633         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16634         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16635 }
16636 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16637
16638 test_241_bio() {
16639         local count=$1
16640         local bsize=$2
16641
16642         for LOOP in $(seq $count); do
16643                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16644                 cancel_lru_locks $OSC || true
16645         done
16646 }
16647
16648 test_241_dio() {
16649         local count=$1
16650         local bsize=$2
16651
16652         for LOOP in $(seq $1); do
16653                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16654                         2>/dev/null
16655         done
16656 }
16657
16658 test_241a() { # was test_241
16659         local bsize=$PAGE_SIZE
16660
16661         (( bsize < 40960 )) && bsize=40960
16662         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16663         ls -la $DIR/$tfile
16664         cancel_lru_locks $OSC
16665         test_241_bio 1000 $bsize &
16666         PID=$!
16667         test_241_dio 1000 $bsize
16668         wait $PID
16669 }
16670 run_test 241a "bio vs dio"
16671
16672 test_241b() {
16673         local bsize=$PAGE_SIZE
16674
16675         (( bsize < 40960 )) && bsize=40960
16676         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16677         ls -la $DIR/$tfile
16678         test_241_dio 1000 $bsize &
16679         PID=$!
16680         test_241_dio 1000 $bsize
16681         wait $PID
16682 }
16683 run_test 241b "dio vs dio"
16684
16685 test_242() {
16686         remote_mds_nodsh && skip "remote MDS with nodsh"
16687
16688         mkdir -p $DIR/$tdir
16689         touch $DIR/$tdir/$tfile
16690
16691         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16692         do_facet mds1 lctl set_param fail_loc=0x105
16693         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16694
16695         do_facet mds1 lctl set_param fail_loc=0
16696         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16697 }
16698 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16699
16700 test_243()
16701 {
16702         test_mkdir $DIR/$tdir
16703         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16704 }
16705 run_test 243 "various group lock tests"
16706
16707 test_244()
16708 {
16709         test_mkdir $DIR/$tdir
16710         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16711         sendfile_grouplock $DIR/$tdir/$tfile || \
16712                 error "sendfile+grouplock failed"
16713         rm -rf $DIR/$tdir
16714 }
16715 run_test 244 "sendfile with group lock tests"
16716
16717 test_245() {
16718         local flagname="multi_mod_rpcs"
16719         local connect_data_name="max_mod_rpcs"
16720         local out
16721
16722         # check if multiple modify RPCs flag is set
16723         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16724                 grep "connect_flags:")
16725         echo "$out"
16726
16727         echo "$out" | grep -qw $flagname
16728         if [ $? -ne 0 ]; then
16729                 echo "connect flag $flagname is not set"
16730                 return
16731         fi
16732
16733         # check if multiple modify RPCs data is set
16734         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16735         echo "$out"
16736
16737         echo "$out" | grep -qw $connect_data_name ||
16738                 error "import should have connect data $connect_data_name"
16739 }
16740 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16741
16742 test_246() { # LU-7371
16743         remote_ost_nodsh && skip "remote OST with nodsh"
16744         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16745                 skip "Need OST version >= 2.7.62"
16746
16747         do_facet ost1 $LCTL set_param fail_val=4095
16748 #define OBD_FAIL_OST_READ_SIZE          0x234
16749         do_facet ost1 $LCTL set_param fail_loc=0x234
16750         $LFS setstripe $DIR/$tfile -i 0 -c 1
16751         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16752         cancel_lru_locks $FSNAME-OST0000
16753         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16754 }
16755 run_test 246 "Read file of size 4095 should return right length"
16756
16757 cleanup_247() {
16758         local submount=$1
16759
16760         trap 0
16761         umount_client $submount
16762         rmdir $submount
16763 }
16764
16765 test_247a() {
16766         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16767                 grep -q subtree ||
16768                 skip_env "Fileset feature is not supported"
16769
16770         local submount=${MOUNT}_$tdir
16771
16772         mkdir $MOUNT/$tdir
16773         mkdir -p $submount || error "mkdir $submount failed"
16774         FILESET="$FILESET/$tdir" mount_client $submount ||
16775                 error "mount $submount failed"
16776         trap "cleanup_247 $submount" EXIT
16777         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16778         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16779                 error "read $MOUNT/$tdir/$tfile failed"
16780         cleanup_247 $submount
16781 }
16782 run_test 247a "mount subdir as fileset"
16783
16784 test_247b() {
16785         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16786                 skip_env "Fileset feature is not supported"
16787
16788         local submount=${MOUNT}_$tdir
16789
16790         rm -rf $MOUNT/$tdir
16791         mkdir -p $submount || error "mkdir $submount failed"
16792         SKIP_FILESET=1
16793         FILESET="$FILESET/$tdir" mount_client $submount &&
16794                 error "mount $submount should fail"
16795         rmdir $submount
16796 }
16797 run_test 247b "mount subdir that dose not exist"
16798
16799 test_247c() {
16800         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16801                 skip_env "Fileset feature is not supported"
16802
16803         local submount=${MOUNT}_$tdir
16804
16805         mkdir -p $MOUNT/$tdir/dir1
16806         mkdir -p $submount || error "mkdir $submount failed"
16807         trap "cleanup_247 $submount" EXIT
16808         FILESET="$FILESET/$tdir" mount_client $submount ||
16809                 error "mount $submount failed"
16810         local fid=$($LFS path2fid $MOUNT/)
16811         $LFS fid2path $submount $fid && error "fid2path should fail"
16812         cleanup_247 $submount
16813 }
16814 run_test 247c "running fid2path outside root"
16815
16816 test_247d() {
16817         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16818                 skip "Fileset feature is not supported"
16819
16820         local submount=${MOUNT}_$tdir
16821
16822         mkdir -p $MOUNT/$tdir/dir1
16823         mkdir -p $submount || error "mkdir $submount failed"
16824         FILESET="$FILESET/$tdir" mount_client $submount ||
16825                 error "mount $submount failed"
16826         trap "cleanup_247 $submount" EXIT
16827         local fid=$($LFS path2fid $submount/dir1)
16828         $LFS fid2path $submount $fid || error "fid2path should succeed"
16829         cleanup_247 $submount
16830 }
16831 run_test 247d "running fid2path inside root"
16832
16833 # LU-8037
16834 test_247e() {
16835         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16836                 grep -q subtree ||
16837                 skip "Fileset feature is not supported"
16838
16839         local submount=${MOUNT}_$tdir
16840
16841         mkdir $MOUNT/$tdir
16842         mkdir -p $submount || error "mkdir $submount failed"
16843         FILESET="$FILESET/.." mount_client $submount &&
16844                 error "mount $submount should fail"
16845         rmdir $submount
16846 }
16847 run_test 247e "mount .. as fileset"
16848
16849 test_248() {
16850         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16851         [ -z "$fast_read_sav" ] && skip "no fast read support"
16852
16853         # create a large file for fast read verification
16854         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16855
16856         # make sure the file is created correctly
16857         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16858                 { rm -f $DIR/$tfile; skip "file creation error"; }
16859
16860         echo "Test 1: verify that fast read is 4 times faster on cache read"
16861
16862         # small read with fast read enabled
16863         $LCTL set_param -n llite.*.fast_read=1
16864         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16865                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16866                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16867         # small read with fast read disabled
16868         $LCTL set_param -n llite.*.fast_read=0
16869         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16870                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16871                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16872
16873         # verify that fast read is 4 times faster for cache read
16874         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16875                 error_not_in_vm "fast read was not 4 times faster: " \
16876                            "$t_fast vs $t_slow"
16877
16878         echo "Test 2: verify the performance between big and small read"
16879         $LCTL set_param -n llite.*.fast_read=1
16880
16881         # 1k non-cache read
16882         cancel_lru_locks osc
16883         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16884                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16885                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16886
16887         # 1M non-cache read
16888         cancel_lru_locks osc
16889         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16890                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16891                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16892
16893         # verify that big IO is not 4 times faster than small IO
16894         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16895                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16896
16897         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16898         rm -f $DIR/$tfile
16899 }
16900 run_test 248 "fast read verification"
16901
16902 test_249() { # LU-7890
16903         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16904                 skip "Need at least version 2.8.54"
16905
16906         rm -f $DIR/$tfile
16907         $LFS setstripe -c 1 $DIR/$tfile
16908         # Offset 2T == 4k * 512M
16909         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16910                 error "dd to 2T offset failed"
16911 }
16912 run_test 249 "Write above 2T file size"
16913
16914 test_250() {
16915         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16916          && skip "no 16TB file size limit on ZFS"
16917
16918         $LFS setstripe -c 1 $DIR/$tfile
16919         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16920         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16921         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16922         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16923                 conv=notrunc,fsync && error "append succeeded"
16924         return 0
16925 }
16926 run_test 250 "Write above 16T limit"
16927
16928 test_251() {
16929         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16930
16931         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16932         #Skip once - writing the first stripe will succeed
16933         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16934         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16935                 error "short write happened"
16936
16937         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16938         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16939                 error "short read happened"
16940
16941         rm -f $DIR/$tfile
16942 }
16943 run_test 251 "Handling short read and write correctly"
16944
16945 test_252() {
16946         remote_mds_nodsh && skip "remote MDS with nodsh"
16947         remote_ost_nodsh && skip "remote OST with nodsh"
16948         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16949                 skip_env "ldiskfs only test"
16950         fi
16951
16952         local tgt
16953         local dev
16954         local out
16955         local uuid
16956         local num
16957         local gen
16958
16959         # check lr_reader on OST0000
16960         tgt=ost1
16961         dev=$(facet_device $tgt)
16962         out=$(do_facet $tgt $LR_READER $dev)
16963         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16964         echo "$out"
16965         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16966         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16967                 error "Invalid uuid returned by $LR_READER on target $tgt"
16968         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16969
16970         # check lr_reader -c on MDT0000
16971         tgt=mds1
16972         dev=$(facet_device $tgt)
16973         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16974                 skip "$LR_READER does not support additional options"
16975         fi
16976         out=$(do_facet $tgt $LR_READER -c $dev)
16977         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16978         echo "$out"
16979         num=$(echo "$out" | grep -c "mdtlov")
16980         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16981                 error "Invalid number of mdtlov clients returned by $LR_READER"
16982         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16983
16984         # check lr_reader -cr on MDT0000
16985         out=$(do_facet $tgt $LR_READER -cr $dev)
16986         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16987         echo "$out"
16988         echo "$out" | grep -q "^reply_data:$" ||
16989                 error "$LR_READER should have returned 'reply_data' section"
16990         num=$(echo "$out" | grep -c "client_generation")
16991         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16992 }
16993 run_test 252 "check lr_reader tool"
16994
16995 test_253() {
16996         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16997         remote_mds_nodsh && skip "remote MDS with nodsh"
16998         remote_mgs_nodsh && skip "remote MGS with nodsh"
16999
17000         local ostidx=0
17001         local rc=0
17002         local ost_name=$(ostname_from_index $ostidx)
17003
17004         # on the mdt's osc
17005         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17006         do_facet $SINGLEMDS $LCTL get_param -n \
17007                 osp.$mdtosc_proc1.reserved_mb_high ||
17008                 skip  "remote MDS does not support reserved_mb_high"
17009
17010         rm -rf $DIR/$tdir
17011         wait_mds_ost_sync
17012         wait_delete_completed
17013         mkdir $DIR/$tdir
17014
17015         if ! combined_mgs_mds ; then
17016                 mount_mgs_client
17017         fi
17018         pool_add $TESTNAME || error "Pool creation failed"
17019         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17020
17021         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17022                 error "Setstripe failed"
17023
17024         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17025
17026         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17027                     grep "watermarks")
17028         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17029
17030         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17031                         osp.$mdtosc_proc1.prealloc_status)
17032         echo "prealloc_status $oa_status"
17033
17034         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17035                 error "File creation should fail"
17036
17037         #object allocation was stopped, but we still able to append files
17038         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17039                 oflag=append || error "Append failed"
17040
17041         rm -f $DIR/$tdir/$tfile.0
17042
17043         # For this test, we want to delete the files we created to go out of
17044         # space but leave the watermark, so we remain nearly out of space
17045         ost_watermarks_enospc_delete_files $tfile $ostidx
17046
17047         wait_delete_completed
17048
17049         sleep_maxage
17050
17051         for i in $(seq 10 12); do
17052                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17053                         2>/dev/null || error "File creation failed after rm"
17054         done
17055
17056         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17057                         osp.$mdtosc_proc1.prealloc_status)
17058         echo "prealloc_status $oa_status"
17059
17060         if (( oa_status != 0 )); then
17061                 error "Object allocation still disable after rm"
17062         fi
17063
17064         if ! combined_mgs_mds ; then
17065                 umount_mgs_client
17066         fi
17067 }
17068 run_test 253 "Check object allocation limit"
17069
17070 test_254() {
17071         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17072         remote_mds_nodsh && skip "remote MDS with nodsh"
17073         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17074                 skip "MDS does not support changelog_size"
17075
17076         local cl_user
17077         local MDT0=$(facet_svc $SINGLEMDS)
17078
17079         changelog_register || error "changelog_register failed"
17080
17081         changelog_clear 0 || error "changelog_clear failed"
17082
17083         local size1=$(do_facet $SINGLEMDS \
17084                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17085         echo "Changelog size $size1"
17086
17087         rm -rf $DIR/$tdir
17088         $LFS mkdir -i 0 $DIR/$tdir
17089         # change something
17090         mkdir -p $DIR/$tdir/pics/2008/zachy
17091         touch $DIR/$tdir/pics/2008/zachy/timestamp
17092         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17093         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17094         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17095         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17096         rm $DIR/$tdir/pics/desktop.jpg
17097
17098         local size2=$(do_facet $SINGLEMDS \
17099                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17100         echo "Changelog size after work $size2"
17101
17102         (( $size2 > $size1 )) ||
17103                 error "new Changelog size=$size2 less than old size=$size1"
17104 }
17105 run_test 254 "Check changelog size"
17106
17107 ladvise_no_type()
17108 {
17109         local type=$1
17110         local file=$2
17111
17112         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17113                 awk -F: '{print $2}' | grep $type > /dev/null
17114         if [ $? -ne 0 ]; then
17115                 return 0
17116         fi
17117         return 1
17118 }
17119
17120 ladvise_no_ioctl()
17121 {
17122         local file=$1
17123
17124         lfs ladvise -a willread $file > /dev/null 2>&1
17125         if [ $? -eq 0 ]; then
17126                 return 1
17127         fi
17128
17129         lfs ladvise -a willread $file 2>&1 |
17130                 grep "Inappropriate ioctl for device" > /dev/null
17131         if [ $? -eq 0 ]; then
17132                 return 0
17133         fi
17134         return 1
17135 }
17136
17137 percent() {
17138         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17139 }
17140
17141 # run a random read IO workload
17142 # usage: random_read_iops <filename> <filesize> <iosize>
17143 random_read_iops() {
17144         local file=$1
17145         local fsize=$2
17146         local iosize=${3:-4096}
17147
17148         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17149                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17150 }
17151
17152 drop_file_oss_cache() {
17153         local file="$1"
17154         local nodes="$2"
17155
17156         $LFS ladvise -a dontneed $file 2>/dev/null ||
17157                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17158 }
17159
17160 ladvise_willread_performance()
17161 {
17162         local repeat=10
17163         local average_origin=0
17164         local average_cache=0
17165         local average_ladvise=0
17166
17167         for ((i = 1; i <= $repeat; i++)); do
17168                 echo "Iter $i/$repeat: reading without willread hint"
17169                 cancel_lru_locks osc
17170                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17171                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17172                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17173                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17174
17175                 cancel_lru_locks osc
17176                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17177                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17178                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17179
17180                 cancel_lru_locks osc
17181                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17182                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17183                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17184                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17185                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17186         done
17187         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17188         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17189         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17190
17191         speedup_cache=$(percent $average_cache $average_origin)
17192         speedup_ladvise=$(percent $average_ladvise $average_origin)
17193
17194         echo "Average uncached read: $average_origin"
17195         echo "Average speedup with OSS cached read: " \
17196                 "$average_cache = +$speedup_cache%"
17197         echo "Average speedup with ladvise willread: " \
17198                 "$average_ladvise = +$speedup_ladvise%"
17199
17200         local lowest_speedup=20
17201         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17202                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17203                         "got $average_cache%. Skipping ladvise willread check."
17204                 return 0
17205         fi
17206
17207         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17208         # it is still good to run until then to exercise 'ladvise willread'
17209         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17210                 [ "$ost1_FSTYPE" = "zfs" ] &&
17211                 echo "osd-zfs does not support dontneed or drop_caches" &&
17212                 return 0
17213
17214         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17215         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17216                 error_not_in_vm "Speedup with willread is less than " \
17217                         "$lowest_speedup%, got $average_ladvise%"
17218 }
17219
17220 test_255a() {
17221         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17222                 skip "lustre < 2.8.54 does not support ladvise "
17223         remote_ost_nodsh && skip "remote OST with nodsh"
17224
17225         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17226
17227         ladvise_no_type willread $DIR/$tfile &&
17228                 skip "willread ladvise is not supported"
17229
17230         ladvise_no_ioctl $DIR/$tfile &&
17231                 skip "ladvise ioctl is not supported"
17232
17233         local size_mb=100
17234         local size=$((size_mb * 1048576))
17235         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17236                 error "dd to $DIR/$tfile failed"
17237
17238         lfs ladvise -a willread $DIR/$tfile ||
17239                 error "Ladvise failed with no range argument"
17240
17241         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17242                 error "Ladvise failed with no -l or -e argument"
17243
17244         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17245                 error "Ladvise failed with only -e argument"
17246
17247         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17248                 error "Ladvise failed with only -l argument"
17249
17250         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17251                 error "End offset should not be smaller than start offset"
17252
17253         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17254                 error "End offset should not be equal to start offset"
17255
17256         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17257                 error "Ladvise failed with overflowing -s argument"
17258
17259         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17260                 error "Ladvise failed with overflowing -e argument"
17261
17262         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17263                 error "Ladvise failed with overflowing -l argument"
17264
17265         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17266                 error "Ladvise succeeded with conflicting -l and -e arguments"
17267
17268         echo "Synchronous ladvise should wait"
17269         local delay=4
17270 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17271         do_nodes $(comma_list $(osts_nodes)) \
17272                 $LCTL set_param fail_val=$delay fail_loc=0x237
17273
17274         local start_ts=$SECONDS
17275         lfs ladvise -a willread $DIR/$tfile ||
17276                 error "Ladvise failed with no range argument"
17277         local end_ts=$SECONDS
17278         local inteval_ts=$((end_ts - start_ts))
17279
17280         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17281                 error "Synchronous advice didn't wait reply"
17282         fi
17283
17284         echo "Asynchronous ladvise shouldn't wait"
17285         local start_ts=$SECONDS
17286         lfs ladvise -a willread -b $DIR/$tfile ||
17287                 error "Ladvise failed with no range argument"
17288         local end_ts=$SECONDS
17289         local inteval_ts=$((end_ts - start_ts))
17290
17291         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17292                 error "Asynchronous advice blocked"
17293         fi
17294
17295         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17296         ladvise_willread_performance
17297 }
17298 run_test 255a "check 'lfs ladvise -a willread'"
17299
17300 facet_meminfo() {
17301         local facet=$1
17302         local info=$2
17303
17304         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17305 }
17306
17307 test_255b() {
17308         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17309                 skip "lustre < 2.8.54 does not support ladvise "
17310         remote_ost_nodsh && skip "remote OST with nodsh"
17311
17312         lfs setstripe -c 1 -i 0 $DIR/$tfile
17313
17314         ladvise_no_type dontneed $DIR/$tfile &&
17315                 skip "dontneed ladvise is not supported"
17316
17317         ladvise_no_ioctl $DIR/$tfile &&
17318                 skip "ladvise ioctl is not supported"
17319
17320         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17321                 [ "$ost1_FSTYPE" = "zfs" ] &&
17322                 skip "zfs-osd does not support 'ladvise dontneed'"
17323
17324         local size_mb=100
17325         local size=$((size_mb * 1048576))
17326         # In order to prevent disturbance of other processes, only check 3/4
17327         # of the memory usage
17328         local kibibytes=$((size_mb * 1024 * 3 / 4))
17329
17330         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17331                 error "dd to $DIR/$tfile failed"
17332
17333         #force write to complete before dropping OST cache & checking memory
17334         sync
17335
17336         local total=$(facet_meminfo ost1 MemTotal)
17337         echo "Total memory: $total KiB"
17338
17339         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17340         local before_read=$(facet_meminfo ost1 Cached)
17341         echo "Cache used before read: $before_read KiB"
17342
17343         lfs ladvise -a willread $DIR/$tfile ||
17344                 error "Ladvise willread failed"
17345         local after_read=$(facet_meminfo ost1 Cached)
17346         echo "Cache used after read: $after_read KiB"
17347
17348         lfs ladvise -a dontneed $DIR/$tfile ||
17349                 error "Ladvise dontneed again failed"
17350         local no_read=$(facet_meminfo ost1 Cached)
17351         echo "Cache used after dontneed ladvise: $no_read KiB"
17352
17353         if [ $total -lt $((before_read + kibibytes)) ]; then
17354                 echo "Memory is too small, abort checking"
17355                 return 0
17356         fi
17357
17358         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17359                 error "Ladvise willread should use more memory" \
17360                         "than $kibibytes KiB"
17361         fi
17362
17363         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17364                 error "Ladvise dontneed should release more memory" \
17365                         "than $kibibytes KiB"
17366         fi
17367 }
17368 run_test 255b "check 'lfs ladvise -a dontneed'"
17369
17370 test_255c() {
17371         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17372                 skip "lustre < 2.10.53 does not support lockahead"
17373
17374         local count
17375         local new_count
17376         local difference
17377         local i
17378         local rc
17379
17380         test_mkdir -p $DIR/$tdir
17381         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17382
17383         #test 10 returns only success/failure
17384         i=10
17385         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17386         rc=$?
17387         if [ $rc -eq 255 ]; then
17388                 error "Ladvise test${i} failed, ${rc}"
17389         fi
17390
17391         #test 11 counts lock enqueue requests, all others count new locks
17392         i=11
17393         count=$(do_facet ost1 \
17394                 $LCTL get_param -n ost.OSS.ost.stats)
17395         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17396
17397         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17398         rc=$?
17399         if [ $rc -eq 255 ]; then
17400                 error "Ladvise test${i} failed, ${rc}"
17401         fi
17402
17403         new_count=$(do_facet ost1 \
17404                 $LCTL get_param -n ost.OSS.ost.stats)
17405         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17406                    awk '{ print $2 }')
17407
17408         difference="$((new_count - count))"
17409         if [ $difference -ne $rc ]; then
17410                 error "Ladvise test${i}, bad enqueue count, returned " \
17411                       "${rc}, actual ${difference}"
17412         fi
17413
17414         for i in $(seq 12 21); do
17415                 # If we do not do this, we run the risk of having too many
17416                 # locks and starting lock cancellation while we are checking
17417                 # lock counts.
17418                 cancel_lru_locks osc
17419
17420                 count=$($LCTL get_param -n \
17421                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17422
17423                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17424                 rc=$?
17425                 if [ $rc -eq 255 ]; then
17426                         error "Ladvise test ${i} failed, ${rc}"
17427                 fi
17428
17429                 new_count=$($LCTL get_param -n \
17430                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17431                 difference="$((new_count - count))"
17432
17433                 # Test 15 output is divided by 100 to map down to valid return
17434                 if [ $i -eq 15 ]; then
17435                         rc="$((rc * 100))"
17436                 fi
17437
17438                 if [ $difference -ne $rc ]; then
17439                         error "Ladvise test ${i}, bad lock count, returned " \
17440                               "${rc}, actual ${difference}"
17441                 fi
17442         done
17443
17444         #test 22 returns only success/failure
17445         i=22
17446         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17447         rc=$?
17448         if [ $rc -eq 255 ]; then
17449                 error "Ladvise test${i} failed, ${rc}"
17450         fi
17451 }
17452 run_test 255c "suite of ladvise lockahead tests"
17453
17454 test_256() {
17455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17456         remote_mds_nodsh && skip "remote MDS with nodsh"
17457         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17458         changelog_users $SINGLEMDS | grep "^cl" &&
17459                 skip "active changelog user"
17460
17461         local cl_user
17462         local cat_sl
17463         local mdt_dev
17464
17465         mdt_dev=$(mdsdevname 1)
17466         echo $mdt_dev
17467
17468         changelog_register || error "changelog_register failed"
17469
17470         rm -rf $DIR/$tdir
17471         mkdir -p $DIR/$tdir
17472
17473         changelog_clear 0 || error "changelog_clear failed"
17474
17475         # change something
17476         touch $DIR/$tdir/{1..10}
17477
17478         # stop the MDT
17479         stop $SINGLEMDS || error "Fail to stop MDT"
17480
17481         # remount the MDT
17482
17483         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17484
17485         #after mount new plainllog is used
17486         touch $DIR/$tdir/{11..19}
17487         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
17488         stack_trap "rm -f $tmpfile"
17489         cat_sl=$(do_facet $SINGLEMDS "sync; \
17490                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17491                  llog_reader $tmpfile | grep -c type=1064553b")
17492         do_facet $SINGLEMDS llog_reader $tmpfile
17493
17494         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17495
17496         changelog_clear 0 || error "changelog_clear failed"
17497
17498         cat_sl=$(do_facet $SINGLEMDS "sync; \
17499                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17500                  llog_reader $tmpfile | grep -c type=1064553b")
17501
17502         if (( cat_sl == 2 )); then
17503                 error "Empty plain llog was not deleted from changelog catalog"
17504         elif (( cat_sl != 1 )); then
17505                 error "Active plain llog shouldn't be deleted from catalog"
17506         fi
17507 }
17508 run_test 256 "Check llog delete for empty and not full state"
17509
17510 test_257() {
17511         remote_mds_nodsh && skip "remote MDS with nodsh"
17512         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17513                 skip "Need MDS version at least 2.8.55"
17514
17515         test_mkdir $DIR/$tdir
17516
17517         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17518                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17519         stat $DIR/$tdir
17520
17521 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17522         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17523         local facet=mds$((mdtidx + 1))
17524         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17525         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17526
17527         stop $facet || error "stop MDS failed"
17528         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17529                 error "start MDS fail"
17530         wait_recovery_complete $facet
17531 }
17532 run_test 257 "xattr locks are not lost"
17533
17534 # Verify we take the i_mutex when security requires it
17535 test_258a() {
17536 #define OBD_FAIL_IMUTEX_SEC 0x141c
17537         $LCTL set_param fail_loc=0x141c
17538         touch $DIR/$tfile
17539         chmod u+s $DIR/$tfile
17540         chmod a+rwx $DIR/$tfile
17541         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17542         RC=$?
17543         if [ $RC -ne 0 ]; then
17544                 error "error, failed to take i_mutex, rc=$?"
17545         fi
17546         rm -f $DIR/$tfile
17547 }
17548 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17549
17550 # Verify we do NOT take the i_mutex in the normal case
17551 test_258b() {
17552 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17553         $LCTL set_param fail_loc=0x141d
17554         touch $DIR/$tfile
17555         chmod a+rwx $DIR
17556         chmod a+rw $DIR/$tfile
17557         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17558         RC=$?
17559         if [ $RC -ne 0 ]; then
17560                 error "error, took i_mutex unnecessarily, rc=$?"
17561         fi
17562         rm -f $DIR/$tfile
17563
17564 }
17565 run_test 258b "verify i_mutex security behavior"
17566
17567 test_259() {
17568         local file=$DIR/$tfile
17569         local before
17570         local after
17571
17572         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17573
17574         stack_trap "rm -f $file" EXIT
17575
17576         wait_delete_completed
17577         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17578         echo "before: $before"
17579
17580         $LFS setstripe -i 0 -c 1 $file
17581         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17582         sync_all_data
17583         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17584         echo "after write: $after"
17585
17586 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17587         do_facet ost1 $LCTL set_param fail_loc=0x2301
17588         $TRUNCATE $file 0
17589         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17590         echo "after truncate: $after"
17591
17592         stop ost1
17593         do_facet ost1 $LCTL set_param fail_loc=0
17594         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17595         sleep 2
17596         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17597         echo "after restart: $after"
17598         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17599                 error "missing truncate?"
17600
17601         return 0
17602 }
17603 run_test 259 "crash at delayed truncate"
17604
17605 test_260() {
17606 #define OBD_FAIL_MDC_CLOSE               0x806
17607         $LCTL set_param fail_loc=0x80000806
17608         touch $DIR/$tfile
17609
17610 }
17611 run_test 260 "Check mdc_close fail"
17612
17613 ### Data-on-MDT sanity tests ###
17614 test_270a() {
17615         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17616                 skip "Need MDS version at least 2.10.55 for DoM"
17617
17618         # create DoM file
17619         local dom=$DIR/$tdir/dom_file
17620         local tmp=$DIR/$tdir/tmp_file
17621
17622         mkdir -p $DIR/$tdir
17623
17624         # basic checks for DoM component creation
17625         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17626                 error "Can set MDT layout to non-first entry"
17627
17628         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17629                 error "Can define multiple entries as MDT layout"
17630
17631         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17632
17633         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17634         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17635         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17636
17637         local mdtidx=$($LFS getstripe -m $dom)
17638         local mdtname=MDT$(printf %04x $mdtidx)
17639         local facet=mds$((mdtidx + 1))
17640         local space_check=1
17641
17642         # Skip free space checks with ZFS
17643         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17644
17645         # write
17646         sync
17647         local size_tmp=$((65536 * 3))
17648         local mdtfree1=$(do_facet $facet \
17649                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17650
17651         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17652         # check also direct IO along write
17653         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17654         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17655         sync
17656         cmp $tmp $dom || error "file data is different"
17657         [ $(stat -c%s $dom) == $size_tmp ] ||
17658                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17659         if [ $space_check == 1 ]; then
17660                 local mdtfree2=$(do_facet $facet \
17661                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17662
17663                 # increase in usage from by $size_tmp
17664                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17665                         error "MDT free space wrong after write: " \
17666                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17667         fi
17668
17669         # truncate
17670         local size_dom=10000
17671
17672         $TRUNCATE $dom $size_dom
17673         [ $(stat -c%s $dom) == $size_dom ] ||
17674                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17675         if [ $space_check == 1 ]; then
17676                 mdtfree1=$(do_facet $facet \
17677                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17678                 # decrease in usage from $size_tmp to new $size_dom
17679                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17680                   $(((size_tmp - size_dom) / 1024)) ] ||
17681                         error "MDT free space is wrong after truncate: " \
17682                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17683         fi
17684
17685         # append
17686         cat $tmp >> $dom
17687         sync
17688         size_dom=$((size_dom + size_tmp))
17689         [ $(stat -c%s $dom) == $size_dom ] ||
17690                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17691         if [ $space_check == 1 ]; then
17692                 mdtfree2=$(do_facet $facet \
17693                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17694                 # increase in usage by $size_tmp from previous
17695                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17696                         error "MDT free space is wrong after append: " \
17697                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17698         fi
17699
17700         # delete
17701         rm $dom
17702         if [ $space_check == 1 ]; then
17703                 mdtfree1=$(do_facet $facet \
17704                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17705                 # decrease in usage by $size_dom from previous
17706                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17707                         error "MDT free space is wrong after removal: " \
17708                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17709         fi
17710
17711         # combined striping
17712         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17713                 error "Can't create DoM + OST striping"
17714
17715         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17716         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17717         # check also direct IO along write
17718         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17719         sync
17720         cmp $tmp $dom || error "file data is different"
17721         [ $(stat -c%s $dom) == $size_tmp ] ||
17722                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17723         rm $dom $tmp
17724
17725         return 0
17726 }
17727 run_test 270a "DoM: basic functionality tests"
17728
17729 test_270b() {
17730         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17731                 skip "Need MDS version at least 2.10.55"
17732
17733         local dom=$DIR/$tdir/dom_file
17734         local max_size=1048576
17735
17736         mkdir -p $DIR/$tdir
17737         $LFS setstripe -E $max_size -L mdt $dom
17738
17739         # truncate over the limit
17740         $TRUNCATE $dom $(($max_size + 1)) &&
17741                 error "successful truncate over the maximum size"
17742         # write over the limit
17743         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17744                 error "successful write over the maximum size"
17745         # append over the limit
17746         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17747         echo "12345" >> $dom && error "successful append over the maximum size"
17748         rm $dom
17749
17750         return 0
17751 }
17752 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17753
17754 test_270c() {
17755         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17756                 skip "Need MDS version at least 2.10.55"
17757
17758         mkdir -p $DIR/$tdir
17759         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17760
17761         # check files inherit DoM EA
17762         touch $DIR/$tdir/first
17763         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17764                 error "bad pattern"
17765         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17766                 error "bad stripe count"
17767         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17768                 error "bad stripe size"
17769
17770         # check directory inherits DoM EA and uses it as default
17771         mkdir $DIR/$tdir/subdir
17772         touch $DIR/$tdir/subdir/second
17773         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17774                 error "bad pattern in sub-directory"
17775         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17776                 error "bad stripe count in sub-directory"
17777         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17778                 error "bad stripe size in sub-directory"
17779         return 0
17780 }
17781 run_test 270c "DoM: DoM EA inheritance tests"
17782
17783 test_270d() {
17784         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17785                 skip "Need MDS version at least 2.10.55"
17786
17787         mkdir -p $DIR/$tdir
17788         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17789
17790         # inherit default DoM striping
17791         mkdir $DIR/$tdir/subdir
17792         touch $DIR/$tdir/subdir/f1
17793
17794         # change default directory striping
17795         $LFS setstripe -c 1 $DIR/$tdir/subdir
17796         touch $DIR/$tdir/subdir/f2
17797         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17798                 error "wrong default striping in file 2"
17799         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17800                 error "bad pattern in file 2"
17801         return 0
17802 }
17803 run_test 270d "DoM: change striping from DoM to RAID0"
17804
17805 test_270e() {
17806         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17807                 skip "Need MDS version at least 2.10.55"
17808
17809         mkdir -p $DIR/$tdir/dom
17810         mkdir -p $DIR/$tdir/norm
17811         DOMFILES=20
17812         NORMFILES=10
17813         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17814         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17815
17816         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17817         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17818
17819         # find DoM files by layout
17820         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17821         [ $NUM -eq  $DOMFILES ] ||
17822                 error "lfs find -L: found $NUM, expected $DOMFILES"
17823         echo "Test 1: lfs find 20 DOM files by layout: OK"
17824
17825         # there should be 1 dir with default DOM striping
17826         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17827         [ $NUM -eq  1 ] ||
17828                 error "lfs find -L: found $NUM, expected 1 dir"
17829         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17830
17831         # find DoM files by stripe size
17832         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17833         [ $NUM -eq  $DOMFILES ] ||
17834                 error "lfs find -S: found $NUM, expected $DOMFILES"
17835         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17836
17837         # find files by stripe offset except DoM files
17838         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17839         [ $NUM -eq  $NORMFILES ] ||
17840                 error "lfs find -i: found $NUM, expected $NORMFILES"
17841         echo "Test 5: lfs find no DOM files by stripe index: OK"
17842         return 0
17843 }
17844 run_test 270e "DoM: lfs find with DoM files test"
17845
17846 test_270f() {
17847         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17848                 skip "Need MDS version at least 2.10.55"
17849
17850         local mdtname=${FSNAME}-MDT0000-mdtlov
17851         local dom=$DIR/$tdir/dom_file
17852         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17853                                                 lod.$mdtname.dom_stripesize)
17854         local dom_limit=131072
17855
17856         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17857         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17858                                                 lod.$mdtname.dom_stripesize)
17859         [ ${dom_limit} -eq ${dom_current} ] ||
17860                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17861
17862         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17863         $LFS setstripe -d $DIR/$tdir
17864         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17865                 error "Can't set directory default striping"
17866
17867         # exceed maximum stripe size
17868         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17869                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17870         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17871                 error "Able to create DoM component size more than LOD limit"
17872
17873         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17874         dom_current=$(do_facet mds1 $LCTL get_param -n \
17875                                                 lod.$mdtname.dom_stripesize)
17876         [ 0 -eq ${dom_current} ] ||
17877                 error "Can't set zero DoM stripe limit"
17878         rm $dom
17879
17880         # attempt to create DoM file on server with disabled DoM should
17881         # remove DoM entry from layout and be succeed
17882         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17883                 error "Can't create DoM file (DoM is disabled)"
17884         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17885                 error "File has DoM component while DoM is disabled"
17886         rm $dom
17887
17888         # attempt to create DoM file with only DoM stripe should return error
17889         $LFS setstripe -E $dom_limit -L mdt $dom &&
17890                 error "Able to create DoM-only file while DoM is disabled"
17891
17892         # too low values to be aligned with smallest stripe size 64K
17893         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17894         dom_current=$(do_facet mds1 $LCTL get_param -n \
17895                                                 lod.$mdtname.dom_stripesize)
17896         [ 30000 -eq ${dom_current} ] &&
17897                 error "Can set too small DoM stripe limit"
17898
17899         # 64K is a minimal stripe size in Lustre, expect limit of that size
17900         [ 65536 -eq ${dom_current} ] ||
17901                 error "Limit is not set to 64K but ${dom_current}"
17902
17903         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17904         dom_current=$(do_facet mds1 $LCTL get_param -n \
17905                                                 lod.$mdtname.dom_stripesize)
17906         echo $dom_current
17907         [ 2147483648 -eq ${dom_current} ] &&
17908                 error "Can set too large DoM stripe limit"
17909
17910         do_facet mds1 $LCTL set_param -n \
17911                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17912         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17913                 error "Can't create DoM component size after limit change"
17914         do_facet mds1 $LCTL set_param -n \
17915                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17916         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17917                 error "Can't create DoM file after limit decrease"
17918         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17919                 error "Can create big DoM component after limit decrease"
17920         touch ${dom}_def ||
17921                 error "Can't create file with old default layout"
17922
17923         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17924         return 0
17925 }
17926 run_test 270f "DoM: maximum DoM stripe size checks"
17927
17928 test_271a() {
17929         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17930                 skip "Need MDS version at least 2.10.55"
17931
17932         local dom=$DIR/$tdir/dom
17933
17934         mkdir -p $DIR/$tdir
17935
17936         $LFS setstripe -E 1024K -L mdt $dom
17937
17938         lctl set_param -n mdc.*.stats=clear
17939         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17940         cat $dom > /dev/null
17941         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17942         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17943         ls $dom
17944         rm -f $dom
17945 }
17946 run_test 271a "DoM: data is cached for read after write"
17947
17948 test_271b() {
17949         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17950                 skip "Need MDS version at least 2.10.55"
17951
17952         local dom=$DIR/$tdir/dom
17953
17954         mkdir -p $DIR/$tdir
17955
17956         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17957
17958         lctl set_param -n mdc.*.stats=clear
17959         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17960         cancel_lru_locks mdc
17961         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17962         # second stat to check size is cached on client
17963         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17964         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17965         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17966         rm -f $dom
17967 }
17968 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17969
17970 test_271ba() {
17971         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17972                 skip "Need MDS version at least 2.10.55"
17973
17974         local dom=$DIR/$tdir/dom
17975
17976         mkdir -p $DIR/$tdir
17977
17978         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17979
17980         lctl set_param -n mdc.*.stats=clear
17981         lctl set_param -n osc.*.stats=clear
17982         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17983         cancel_lru_locks mdc
17984         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17985         # second stat to check size is cached on client
17986         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17987         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17988         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17989         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17990         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17991         rm -f $dom
17992 }
17993 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17994
17995
17996 get_mdc_stats() {
17997         local mdtidx=$1
17998         local param=$2
17999         local mdt=MDT$(printf %04x $mdtidx)
18000
18001         if [ -z $param ]; then
18002                 lctl get_param -n mdc.*$mdt*.stats
18003         else
18004                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18005         fi
18006 }
18007
18008 test_271c() {
18009         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18010                 skip "Need MDS version at least 2.10.55"
18011
18012         local dom=$DIR/$tdir/dom
18013
18014         mkdir -p $DIR/$tdir
18015
18016         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18017
18018         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18019         local facet=mds$((mdtidx + 1))
18020
18021         cancel_lru_locks mdc
18022         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18023         createmany -o $dom 1000
18024         lctl set_param -n mdc.*.stats=clear
18025         smalliomany -w $dom 1000 200
18026         get_mdc_stats $mdtidx
18027         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18028         # Each file has 1 open, 1 IO enqueues, total 2000
18029         # but now we have also +1 getxattr for security.capability, total 3000
18030         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18031         unlinkmany $dom 1000
18032
18033         cancel_lru_locks mdc
18034         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18035         createmany -o $dom 1000
18036         lctl set_param -n mdc.*.stats=clear
18037         smalliomany -w $dom 1000 200
18038         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18039         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18040         # for OPEN and IO lock.
18041         [ $((enq - enq_2)) -ge 1000 ] ||
18042                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18043         unlinkmany $dom 1000
18044         return 0
18045 }
18046 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18047
18048 cleanup_271def_tests() {
18049         trap 0
18050         rm -f $1
18051 }
18052
18053 test_271d() {
18054         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18055                 skip "Need MDS version at least 2.10.57"
18056
18057         local dom=$DIR/$tdir/dom
18058         local tmp=$TMP/$tfile
18059         trap "cleanup_271def_tests $tmp" EXIT
18060
18061         mkdir -p $DIR/$tdir
18062
18063         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18064
18065         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18066
18067         cancel_lru_locks mdc
18068         dd if=/dev/urandom of=$tmp bs=1000 count=1
18069         dd if=$tmp of=$dom bs=1000 count=1
18070         cancel_lru_locks mdc
18071
18072         cat /etc/hosts >> $tmp
18073         lctl set_param -n mdc.*.stats=clear
18074
18075         # append data to the same file it should update local page
18076         echo "Append to the same page"
18077         cat /etc/hosts >> $dom
18078         local num=$(get_mdc_stats $mdtidx ost_read)
18079         local ra=$(get_mdc_stats $mdtidx req_active)
18080         local rw=$(get_mdc_stats $mdtidx req_waittime)
18081
18082         [ -z $num ] || error "$num READ RPC occured"
18083         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18084         echo "... DONE"
18085
18086         # compare content
18087         cmp $tmp $dom || error "file miscompare"
18088
18089         cancel_lru_locks mdc
18090         lctl set_param -n mdc.*.stats=clear
18091
18092         echo "Open and read file"
18093         cat $dom > /dev/null
18094         local num=$(get_mdc_stats $mdtidx ost_read)
18095         local ra=$(get_mdc_stats $mdtidx req_active)
18096         local rw=$(get_mdc_stats $mdtidx req_waittime)
18097
18098         [ -z $num ] || error "$num READ RPC occured"
18099         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18100         echo "... DONE"
18101
18102         # compare content
18103         cmp $tmp $dom || error "file miscompare"
18104
18105         return 0
18106 }
18107 run_test 271d "DoM: read on open (1K file in reply buffer)"
18108
18109 test_271f() {
18110         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18111                 skip "Need MDS version at least 2.10.57"
18112
18113         local dom=$DIR/$tdir/dom
18114         local tmp=$TMP/$tfile
18115         trap "cleanup_271def_tests $tmp" EXIT
18116
18117         mkdir -p $DIR/$tdir
18118
18119         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18120
18121         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18122
18123         cancel_lru_locks mdc
18124         dd if=/dev/urandom of=$tmp bs=200000 count=1
18125         dd if=$tmp of=$dom bs=200000 count=1
18126         cancel_lru_locks mdc
18127         cat /etc/hosts >> $tmp
18128         lctl set_param -n mdc.*.stats=clear
18129
18130         echo "Append to the same page"
18131         cat /etc/hosts >> $dom
18132         local num=$(get_mdc_stats $mdtidx ost_read)
18133         local ra=$(get_mdc_stats $mdtidx req_active)
18134         local rw=$(get_mdc_stats $mdtidx req_waittime)
18135
18136         [ -z $num ] || error "$num READ RPC occured"
18137         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18138         echo "... DONE"
18139
18140         # compare content
18141         cmp $tmp $dom || error "file miscompare"
18142
18143         cancel_lru_locks mdc
18144         lctl set_param -n mdc.*.stats=clear
18145
18146         echo "Open and read file"
18147         cat $dom > /dev/null
18148         local num=$(get_mdc_stats $mdtidx ost_read)
18149         local ra=$(get_mdc_stats $mdtidx req_active)
18150         local rw=$(get_mdc_stats $mdtidx req_waittime)
18151
18152         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18153         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18154         echo "... DONE"
18155
18156         # compare content
18157         cmp $tmp $dom || error "file miscompare"
18158
18159         return 0
18160 }
18161 run_test 271f "DoM: read on open (200K file and read tail)"
18162
18163 test_271g() {
18164         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18165                 skip "Skipping due to old client or server version"
18166
18167         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18168         # to get layout
18169         $CHECKSTAT -t file $DIR1/$tfile
18170
18171         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18172         MULTIOP_PID=$!
18173         sleep 1
18174         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18175         $LCTL set_param fail_loc=0x80000314
18176         rm $DIR1/$tfile || error "Unlink fails"
18177         RC=$?
18178         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18179         [ $RC -eq 0 ] || error "Failed write to stale object"
18180 }
18181 run_test 271g "Discard DoM data vs client flush race"
18182
18183 test_272a() {
18184         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18185                 skip "Need MDS version at least 2.11.50"
18186
18187         local dom=$DIR/$tdir/dom
18188         mkdir -p $DIR/$tdir
18189
18190         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18191         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18192                 error "failed to write data into $dom"
18193         local old_md5=$(md5sum $dom)
18194
18195         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18196                 error "failed to migrate to the same DoM component"
18197
18198         local new_md5=$(md5sum $dom)
18199
18200         [ "$old_md5" == "$new_md5" ] ||
18201                 error "md5sum differ: $old_md5, $new_md5"
18202
18203         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18204                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18205 }
18206 run_test 272a "DoM migration: new layout with the same DOM component"
18207
18208 test_272b() {
18209         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18210                 skip "Need MDS version at least 2.11.50"
18211
18212         local dom=$DIR/$tdir/dom
18213         mkdir -p $DIR/$tdir
18214         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18215
18216         local mdtidx=$($LFS getstripe -m $dom)
18217         local mdtname=MDT$(printf %04x $mdtidx)
18218         local facet=mds$((mdtidx + 1))
18219
18220         local mdtfree1=$(do_facet $facet \
18221                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18222         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18223                 error "failed to write data into $dom"
18224         local old_md5=$(md5sum $dom)
18225         cancel_lru_locks mdc
18226         local mdtfree1=$(do_facet $facet \
18227                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18228
18229         $LFS migrate -c2 $dom ||
18230                 error "failed to migrate to the new composite layout"
18231         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18232                 error "MDT stripe was not removed"
18233
18234         cancel_lru_locks mdc
18235         local new_md5=$(md5sum $dom)
18236         [ "$old_md5" != "$new_md5" ] &&
18237                 error "$old_md5 != $new_md5"
18238
18239         # Skip free space checks with ZFS
18240         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18241                 local mdtfree2=$(do_facet $facet \
18242                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18243                 [ $mdtfree2 -gt $mdtfree1 ] ||
18244                         error "MDT space is not freed after migration"
18245         fi
18246         return 0
18247 }
18248 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18249
18250 test_272c() {
18251         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18252                 skip "Need MDS version at least 2.11.50"
18253
18254         local dom=$DIR/$tdir/$tfile
18255         mkdir -p $DIR/$tdir
18256         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18257
18258         local mdtidx=$($LFS getstripe -m $dom)
18259         local mdtname=MDT$(printf %04x $mdtidx)
18260         local facet=mds$((mdtidx + 1))
18261
18262         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18263                 error "failed to write data into $dom"
18264         local old_md5=$(md5sum $dom)
18265         cancel_lru_locks mdc
18266         local mdtfree1=$(do_facet $facet \
18267                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18268
18269         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18270                 error "failed to migrate to the new composite layout"
18271         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18272                 error "MDT stripe was not removed"
18273
18274         cancel_lru_locks mdc
18275         local new_md5=$(md5sum $dom)
18276         [ "$old_md5" != "$new_md5" ] &&
18277                 error "$old_md5 != $new_md5"
18278
18279         # Skip free space checks with ZFS
18280         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18281                 local mdtfree2=$(do_facet $facet \
18282                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18283                 [ $mdtfree2 -gt $mdtfree1 ] ||
18284                         error "MDS space is not freed after migration"
18285         fi
18286         return 0
18287 }
18288 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18289
18290 test_273a() {
18291         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18292                 skip "Need MDS version at least 2.11.50"
18293
18294         # Layout swap cannot be done if either file has DOM component,
18295         # this will never be supported, migration should be used instead
18296
18297         local dom=$DIR/$tdir/$tfile
18298         mkdir -p $DIR/$tdir
18299
18300         $LFS setstripe -c2 ${dom}_plain
18301         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18302         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18303                 error "can swap layout with DoM component"
18304         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18305                 error "can swap layout with DoM component"
18306
18307         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18308         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18309                 error "can swap layout with DoM component"
18310         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18311                 error "can swap layout with DoM component"
18312         return 0
18313 }
18314 run_test 273a "DoM: layout swapping should fail with DOM"
18315
18316 test_275() {
18317         remote_ost_nodsh && skip "remote OST with nodsh"
18318         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18319                 skip "Need OST version >= 2.10.57"
18320
18321         local file=$DIR/$tfile
18322         local oss
18323
18324         oss=$(comma_list $(osts_nodes))
18325
18326         dd if=/dev/urandom of=$file bs=1M count=2 ||
18327                 error "failed to create a file"
18328         cancel_lru_locks osc
18329
18330         #lock 1
18331         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18332                 error "failed to read a file"
18333
18334 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18335         $LCTL set_param fail_loc=0x8000031f
18336
18337         cancel_lru_locks osc &
18338         sleep 1
18339
18340 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18341         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18342         #IO takes another lock, but matches the PENDING one
18343         #and places it to the IO RPC
18344         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18345                 error "failed to read a file with PENDING lock"
18346 }
18347 run_test 275 "Read on a canceled duplicate lock"
18348
18349 test_276() {
18350         remote_ost_nodsh && skip "remote OST with nodsh"
18351         local pid
18352
18353         do_facet ost1 "(while true; do \
18354                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18355                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18356         pid=$!
18357
18358         for LOOP in $(seq 20); do
18359                 stop ost1
18360                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18361         done
18362         kill -9 $pid
18363         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18364                 rm $TMP/sanity_276_pid"
18365 }
18366 run_test 276 "Race between mount and obd_statfs"
18367
18368 test_277() {
18369         $LCTL set_param ldlm.namespaces.*.lru_size=0
18370         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
18371         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18372                         grep ^used_mb | awk '{print $2}')
18373         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
18374         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
18375                 oflag=direct conv=notrunc
18376         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18377                         grep ^used_mb | awk '{print $2}')
18378         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
18379 }
18380 run_test 277 "Direct IO shall drop page cache"
18381
18382 cleanup_test_300() {
18383         trap 0
18384         umask $SAVE_UMASK
18385 }
18386 test_striped_dir() {
18387         local mdt_index=$1
18388         local stripe_count
18389         local stripe_index
18390
18391         mkdir -p $DIR/$tdir
18392
18393         SAVE_UMASK=$(umask)
18394         trap cleanup_test_300 RETURN EXIT
18395
18396         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18397                                                 $DIR/$tdir/striped_dir ||
18398                 error "set striped dir error"
18399
18400         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18401         [ "$mode" = "755" ] || error "expect 755 got $mode"
18402
18403         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18404                 error "getdirstripe failed"
18405         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18406         if [ "$stripe_count" != "2" ]; then
18407                 error "1:stripe_count is $stripe_count, expect 2"
18408         fi
18409         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18410         if [ "$stripe_count" != "2" ]; then
18411                 error "2:stripe_count is $stripe_count, expect 2"
18412         fi
18413
18414         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18415         if [ "$stripe_index" != "$mdt_index" ]; then
18416                 error "stripe_index is $stripe_index, expect $mdt_index"
18417         fi
18418
18419         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18420                 error "nlink error after create striped dir"
18421
18422         mkdir $DIR/$tdir/striped_dir/a
18423         mkdir $DIR/$tdir/striped_dir/b
18424
18425         stat $DIR/$tdir/striped_dir/a ||
18426                 error "create dir under striped dir failed"
18427         stat $DIR/$tdir/striped_dir/b ||
18428                 error "create dir under striped dir failed"
18429
18430         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18431                 error "nlink error after mkdir"
18432
18433         rmdir $DIR/$tdir/striped_dir/a
18434         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18435                 error "nlink error after rmdir"
18436
18437         rmdir $DIR/$tdir/striped_dir/b
18438         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18439                 error "nlink error after rmdir"
18440
18441         chattr +i $DIR/$tdir/striped_dir
18442         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18443                 error "immutable flags not working under striped dir!"
18444         chattr -i $DIR/$tdir/striped_dir
18445
18446         rmdir $DIR/$tdir/striped_dir ||
18447                 error "rmdir striped dir error"
18448
18449         cleanup_test_300
18450
18451         true
18452 }
18453
18454 test_300a() {
18455         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18456                 skip "skipped for lustre < 2.7.0"
18457         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18458         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18459
18460         test_striped_dir 0 || error "failed on striped dir on MDT0"
18461         test_striped_dir 1 || error "failed on striped dir on MDT0"
18462 }
18463 run_test 300a "basic striped dir sanity test"
18464
18465 test_300b() {
18466         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18467                 skip "skipped for lustre < 2.7.0"
18468         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18469         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18470
18471         local i
18472         local mtime1
18473         local mtime2
18474         local mtime3
18475
18476         test_mkdir $DIR/$tdir || error "mkdir fail"
18477         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18478                 error "set striped dir error"
18479         for i in {0..9}; do
18480                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18481                 sleep 1
18482                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18483                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18484                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18485                 sleep 1
18486                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18487                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18488                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18489         done
18490         true
18491 }
18492 run_test 300b "check ctime/mtime for striped dir"
18493
18494 test_300c() {
18495         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18496                 skip "skipped for lustre < 2.7.0"
18497         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18498         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18499
18500         local file_count
18501
18502         mkdir -p $DIR/$tdir
18503         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18504                 error "set striped dir error"
18505
18506         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18507                 error "chown striped dir failed"
18508
18509         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18510                 error "create 5k files failed"
18511
18512         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18513
18514         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18515
18516         rm -rf $DIR/$tdir
18517 }
18518 run_test 300c "chown && check ls under striped directory"
18519
18520 test_300d() {
18521         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18522                 skip "skipped for lustre < 2.7.0"
18523         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18524         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18525
18526         local stripe_count
18527         local file
18528
18529         mkdir -p $DIR/$tdir
18530         $LFS setstripe -c 2 $DIR/$tdir
18531
18532         #local striped directory
18533         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18534                 error "set striped dir error"
18535         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18536                 error "create 10 files failed"
18537
18538         #remote striped directory
18539         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18540                 error "set striped dir error"
18541         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18542                 error "create 10 files failed"
18543
18544         for file in $(find $DIR/$tdir); do
18545                 stripe_count=$($LFS getstripe -c $file)
18546                 [ $stripe_count -eq 2 ] ||
18547                         error "wrong stripe $stripe_count for $file"
18548         done
18549
18550         rm -rf $DIR/$tdir
18551 }
18552 run_test 300d "check default stripe under striped directory"
18553
18554 test_300e() {
18555         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18556                 skip "Need MDS version at least 2.7.55"
18557         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18558         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18559
18560         local stripe_count
18561         local file
18562
18563         mkdir -p $DIR/$tdir
18564
18565         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18566                 error "set striped dir error"
18567
18568         touch $DIR/$tdir/striped_dir/a
18569         touch $DIR/$tdir/striped_dir/b
18570         touch $DIR/$tdir/striped_dir/c
18571
18572         mkdir $DIR/$tdir/striped_dir/dir_a
18573         mkdir $DIR/$tdir/striped_dir/dir_b
18574         mkdir $DIR/$tdir/striped_dir/dir_c
18575
18576         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18577                 error "set striped adir under striped dir error"
18578
18579         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18580                 error "set striped bdir under striped dir error"
18581
18582         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18583                 error "set striped cdir under striped dir error"
18584
18585         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18586                 error "rename dir under striped dir fails"
18587
18588         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18589                 error "rename dir under different stripes fails"
18590
18591         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18592                 error "rename file under striped dir should succeed"
18593
18594         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18595                 error "rename dir under striped dir should succeed"
18596
18597         rm -rf $DIR/$tdir
18598 }
18599 run_test 300e "check rename under striped directory"
18600
18601 test_300f() {
18602         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18603         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18604         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18605                 skip "Need MDS version at least 2.7.55"
18606
18607         local stripe_count
18608         local file
18609
18610         rm -rf $DIR/$tdir
18611         mkdir -p $DIR/$tdir
18612
18613         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18614                 error "set striped dir error"
18615
18616         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18617                 error "set striped dir error"
18618
18619         touch $DIR/$tdir/striped_dir/a
18620         mkdir $DIR/$tdir/striped_dir/dir_a
18621         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18622                 error "create striped dir under striped dir fails"
18623
18624         touch $DIR/$tdir/striped_dir1/b
18625         mkdir $DIR/$tdir/striped_dir1/dir_b
18626         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18627                 error "create striped dir under striped dir fails"
18628
18629         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18630                 error "rename dir under different striped dir should fail"
18631
18632         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18633                 error "rename striped dir under diff striped dir should fail"
18634
18635         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18636                 error "rename file under diff striped dirs fails"
18637
18638         rm -rf $DIR/$tdir
18639 }
18640 run_test 300f "check rename cross striped directory"
18641
18642 test_300_check_default_striped_dir()
18643 {
18644         local dirname=$1
18645         local default_count=$2
18646         local default_index=$3
18647         local stripe_count
18648         local stripe_index
18649         local dir_stripe_index
18650         local dir
18651
18652         echo "checking $dirname $default_count $default_index"
18653         $LFS setdirstripe -D -c $default_count -i $default_index \
18654                                 -t all_char $DIR/$tdir/$dirname ||
18655                 error "set default stripe on striped dir error"
18656         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18657         [ $stripe_count -eq $default_count ] ||
18658                 error "expect $default_count get $stripe_count for $dirname"
18659
18660         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18661         [ $stripe_index -eq $default_index ] ||
18662                 error "expect $default_index get $stripe_index for $dirname"
18663
18664         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18665                                                 error "create dirs failed"
18666
18667         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18668         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18669         for dir in $(find $DIR/$tdir/$dirname/*); do
18670                 stripe_count=$($LFS getdirstripe -c $dir)
18671                 [ $stripe_count -eq $default_count ] ||
18672                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18673                 error "stripe count $default_count != $stripe_count for $dir"
18674
18675                 stripe_index=$($LFS getdirstripe -i $dir)
18676                 [ $default_index -eq -1 ] ||
18677                         [ $stripe_index -eq $default_index ] ||
18678                         error "$stripe_index != $default_index for $dir"
18679
18680                 #check default stripe
18681                 stripe_count=$($LFS getdirstripe -D -c $dir)
18682                 [ $stripe_count -eq $default_count ] ||
18683                 error "default count $default_count != $stripe_count for $dir"
18684
18685                 stripe_index=$($LFS getdirstripe -D -i $dir)
18686                 [ $stripe_index -eq $default_index ] ||
18687                 error "default index $default_index != $stripe_index for $dir"
18688         done
18689         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18690 }
18691
18692 test_300g() {
18693         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18694         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18695                 skip "Need MDS version at least 2.7.55"
18696
18697         local dir
18698         local stripe_count
18699         local stripe_index
18700
18701         mkdir $DIR/$tdir
18702         mkdir $DIR/$tdir/normal_dir
18703
18704         #Checking when client cache stripe index
18705         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18706         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18707                 error "create striped_dir failed"
18708
18709         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18710                 error "create dir0 fails"
18711         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18712         [ $stripe_index -eq 0 ] ||
18713                 error "dir0 expect index 0 got $stripe_index"
18714
18715         mkdir $DIR/$tdir/striped_dir/dir1 ||
18716                 error "create dir1 fails"
18717         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18718         [ $stripe_index -eq 1 ] ||
18719                 error "dir1 expect index 1 got $stripe_index"
18720
18721         #check default stripe count/stripe index
18722         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18723         test_300_check_default_striped_dir normal_dir 1 0
18724         test_300_check_default_striped_dir normal_dir 2 1
18725         test_300_check_default_striped_dir normal_dir 2 -1
18726
18727         #delete default stripe information
18728         echo "delete default stripeEA"
18729         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18730                 error "set default stripe on striped dir error"
18731
18732         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18733         for dir in $(find $DIR/$tdir/normal_dir/*); do
18734                 stripe_count=$($LFS getdirstripe -c $dir)
18735                 [ $stripe_count -eq 0 ] ||
18736                         error "expect 1 get $stripe_count for $dir"
18737                 stripe_index=$($LFS getdirstripe -i $dir)
18738                 [ $stripe_index -eq 0 ] ||
18739                         error "expect 0 get $stripe_index for $dir"
18740         done
18741 }
18742 run_test 300g "check default striped directory for normal directory"
18743
18744 test_300h() {
18745         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18746         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18747                 skip "Need MDS version at least 2.7.55"
18748
18749         local dir
18750         local stripe_count
18751
18752         mkdir $DIR/$tdir
18753         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18754                 error "set striped dir error"
18755
18756         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18757         test_300_check_default_striped_dir striped_dir 1 0
18758         test_300_check_default_striped_dir striped_dir 2 1
18759         test_300_check_default_striped_dir striped_dir 2 -1
18760
18761         #delete default stripe information
18762         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18763                 error "set default stripe on striped dir error"
18764
18765         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18766         for dir in $(find $DIR/$tdir/striped_dir/*); do
18767                 stripe_count=$($LFS getdirstripe -c $dir)
18768                 [ $stripe_count -eq 0 ] ||
18769                         error "expect 1 get $stripe_count for $dir"
18770         done
18771 }
18772 run_test 300h "check default striped directory for striped directory"
18773
18774 test_300i() {
18775         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18776         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18777         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18778                 skip "Need MDS version at least 2.7.55"
18779
18780         local stripe_count
18781         local file
18782
18783         mkdir $DIR/$tdir
18784
18785         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18786                 error "set striped dir error"
18787
18788         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18789                 error "create files under striped dir failed"
18790
18791         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18792                 error "set striped hashdir error"
18793
18794         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18795                 error "create dir0 under hash dir failed"
18796         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18797                 error "create dir1 under hash dir failed"
18798
18799         # unfortunately, we need to umount to clear dir layout cache for now
18800         # once we fully implement dir layout, we can drop this
18801         umount_client $MOUNT || error "umount failed"
18802         mount_client $MOUNT || error "mount failed"
18803
18804         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18805         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18806         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18807
18808         #set the stripe to be unknown hash type
18809         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18810         $LCTL set_param fail_loc=0x1901
18811         for ((i = 0; i < 10; i++)); do
18812                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18813                         error "stat f-$i failed"
18814                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18815         done
18816
18817         touch $DIR/$tdir/striped_dir/f0 &&
18818                 error "create under striped dir with unknown hash should fail"
18819
18820         $LCTL set_param fail_loc=0
18821
18822         umount_client $MOUNT || error "umount failed"
18823         mount_client $MOUNT || error "mount failed"
18824
18825         return 0
18826 }
18827 run_test 300i "client handle unknown hash type striped directory"
18828
18829 test_300j() {
18830         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18831         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18832         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18833                 skip "Need MDS version at least 2.7.55"
18834
18835         local stripe_count
18836         local file
18837
18838         mkdir $DIR/$tdir
18839
18840         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18841         $LCTL set_param fail_loc=0x1702
18842         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18843                 error "set striped dir error"
18844
18845         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18846                 error "create files under striped dir failed"
18847
18848         $LCTL set_param fail_loc=0
18849
18850         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18851
18852         return 0
18853 }
18854 run_test 300j "test large update record"
18855
18856 test_300k() {
18857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18858         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18859         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18860                 skip "Need MDS version at least 2.7.55"
18861
18862         # this test needs a huge transaction
18863         local kb
18864         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18865         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18866
18867         local stripe_count
18868         local file
18869
18870         mkdir $DIR/$tdir
18871
18872         #define OBD_FAIL_LARGE_STRIPE   0x1703
18873         $LCTL set_param fail_loc=0x1703
18874         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18875                 error "set striped dir error"
18876         $LCTL set_param fail_loc=0
18877
18878         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18879                 error "getstripeddir fails"
18880         rm -rf $DIR/$tdir/striped_dir ||
18881                 error "unlink striped dir fails"
18882
18883         return 0
18884 }
18885 run_test 300k "test large striped directory"
18886
18887 test_300l() {
18888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18889         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18890         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18891                 skip "Need MDS version at least 2.7.55"
18892
18893         local stripe_index
18894
18895         test_mkdir -p $DIR/$tdir/striped_dir
18896         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18897                         error "chown $RUNAS_ID failed"
18898         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18899                 error "set default striped dir failed"
18900
18901         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18902         $LCTL set_param fail_loc=0x80000158
18903         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18904
18905         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18906         [ $stripe_index -eq 1 ] ||
18907                 error "expect 1 get $stripe_index for $dir"
18908 }
18909 run_test 300l "non-root user to create dir under striped dir with stale layout"
18910
18911 test_300m() {
18912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18913         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18914         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18915                 skip "Need MDS version at least 2.7.55"
18916
18917         mkdir -p $DIR/$tdir/striped_dir
18918         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18919                 error "set default stripes dir error"
18920
18921         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18922
18923         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18924         [ $stripe_count -eq 0 ] ||
18925                         error "expect 0 get $stripe_count for a"
18926
18927         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18928                 error "set default stripes dir error"
18929
18930         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18931
18932         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18933         [ $stripe_count -eq 0 ] ||
18934                         error "expect 0 get $stripe_count for b"
18935
18936         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18937                 error "set default stripes dir error"
18938
18939         mkdir $DIR/$tdir/striped_dir/c &&
18940                 error "default stripe_index is invalid, mkdir c should fails"
18941
18942         rm -rf $DIR/$tdir || error "rmdir fails"
18943 }
18944 run_test 300m "setstriped directory on single MDT FS"
18945
18946 cleanup_300n() {
18947         local list=$(comma_list $(mdts_nodes))
18948
18949         trap 0
18950         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18951 }
18952
18953 test_300n() {
18954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18955         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18956         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18957                 skip "Need MDS version at least 2.7.55"
18958         remote_mds_nodsh && skip "remote MDS with nodsh"
18959
18960         local stripe_index
18961         local list=$(comma_list $(mdts_nodes))
18962
18963         trap cleanup_300n RETURN EXIT
18964         mkdir -p $DIR/$tdir
18965         chmod 777 $DIR/$tdir
18966         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18967                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18968                 error "create striped dir succeeds with gid=0"
18969
18970         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18971         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18972                 error "create striped dir fails with gid=-1"
18973
18974         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18975         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18976                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18977                 error "set default striped dir succeeds with gid=0"
18978
18979
18980         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18981         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18982                 error "set default striped dir fails with gid=-1"
18983
18984
18985         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18986         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18987                                         error "create test_dir fails"
18988         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18989                                         error "create test_dir1 fails"
18990         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18991                                         error "create test_dir2 fails"
18992         cleanup_300n
18993 }
18994 run_test 300n "non-root user to create dir under striped dir with default EA"
18995
18996 test_300o() {
18997         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18998         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18999         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19000                 skip "Need MDS version at least 2.7.55"
19001
19002         local numfree1
19003         local numfree2
19004
19005         mkdir -p $DIR/$tdir
19006
19007         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19008         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19009         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19010                 skip "not enough free inodes $numfree1 $numfree2"
19011         fi
19012
19013         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19014         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19015         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19016                 skip "not enough free space $numfree1 $numfree2"
19017         fi
19018
19019         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19020                 error "setdirstripe fails"
19021
19022         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19023                 error "create dirs fails"
19024
19025         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19026         ls $DIR/$tdir/striped_dir > /dev/null ||
19027                 error "ls striped dir fails"
19028         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19029                 error "unlink big striped dir fails"
19030 }
19031 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19032
19033 test_300p() {
19034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19035         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19036         remote_mds_nodsh && skip "remote MDS with nodsh"
19037
19038         mkdir -p $DIR/$tdir
19039
19040         #define OBD_FAIL_OUT_ENOSPC     0x1704
19041         do_facet mds2 lctl set_param fail_loc=0x80001704
19042         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19043                  && error "create striped directory should fail"
19044
19045         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19046
19047         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19048         true
19049 }
19050 run_test 300p "create striped directory without space"
19051
19052 test_300q() {
19053         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19054         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19055
19056         local fd=$(free_fd)
19057         local cmd="exec $fd<$tdir"
19058         cd $DIR
19059         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19060         eval $cmd
19061         cmd="exec $fd<&-"
19062         trap "eval $cmd" EXIT
19063         cd $tdir || error "cd $tdir fails"
19064         rmdir  ../$tdir || error "rmdir $tdir fails"
19065         mkdir local_dir && error "create dir succeeds"
19066         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19067         eval $cmd
19068         return 0
19069 }
19070 run_test 300q "create remote directory under orphan directory"
19071
19072 test_300r() {
19073         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19074                 skip "Need MDS version at least 2.7.55" && return
19075         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19076
19077         mkdir $DIR/$tdir
19078
19079         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19080                 error "set striped dir error"
19081
19082         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19083                 error "getstripeddir fails"
19084
19085         local stripe_count
19086         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19087                       awk '/lmv_stripe_count:/ { print $2 }')
19088
19089         [ $MDSCOUNT -ne $stripe_count ] &&
19090                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19091
19092         rm -rf $DIR/$tdir/striped_dir ||
19093                 error "unlink striped dir fails"
19094 }
19095 run_test 300r "test -1 striped directory"
19096
19097 prepare_remote_file() {
19098         mkdir $DIR/$tdir/src_dir ||
19099                 error "create remote source failed"
19100
19101         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19102                  error "cp to remote source failed"
19103         touch $DIR/$tdir/src_dir/a
19104
19105         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19106                 error "create remote target dir failed"
19107
19108         touch $DIR/$tdir/tgt_dir/b
19109
19110         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19111                 error "rename dir cross MDT failed!"
19112
19113         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19114                 error "src_child still exists after rename"
19115
19116         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19117                 error "missing file(a) after rename"
19118
19119         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19120                 error "diff after rename"
19121 }
19122
19123 test_310a() {
19124         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19126
19127         local remote_file=$DIR/$tdir/tgt_dir/b
19128
19129         mkdir -p $DIR/$tdir
19130
19131         prepare_remote_file || error "prepare remote file failed"
19132
19133         #open-unlink file
19134         $OPENUNLINK $remote_file $remote_file ||
19135                 error "openunlink $remote_file failed"
19136         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19137 }
19138 run_test 310a "open unlink remote file"
19139
19140 test_310b() {
19141         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19143
19144         local remote_file=$DIR/$tdir/tgt_dir/b
19145
19146         mkdir -p $DIR/$tdir
19147
19148         prepare_remote_file || error "prepare remote file failed"
19149
19150         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19151         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19152         $CHECKSTAT -t file $remote_file || error "check file failed"
19153 }
19154 run_test 310b "unlink remote file with multiple links while open"
19155
19156 test_310c() {
19157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19158         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19159
19160         local remote_file=$DIR/$tdir/tgt_dir/b
19161
19162         mkdir -p $DIR/$tdir
19163
19164         prepare_remote_file || error "prepare remote file failed"
19165
19166         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19167         multiop_bg_pause $remote_file O_uc ||
19168                         error "mulitop failed for remote file"
19169         MULTIPID=$!
19170         $MULTIOP $DIR/$tfile Ouc
19171         kill -USR1 $MULTIPID
19172         wait $MULTIPID
19173 }
19174 run_test 310c "open-unlink remote file with multiple links"
19175
19176 #LU-4825
19177 test_311() {
19178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19179         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19180         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19181                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19182         remote_mds_nodsh && skip "remote MDS with nodsh"
19183
19184         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19185         local mdts=$(comma_list $(mdts_nodes))
19186
19187         mkdir -p $DIR/$tdir
19188         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19189         createmany -o $DIR/$tdir/$tfile. 1000
19190
19191         # statfs data is not real time, let's just calculate it
19192         old_iused=$((old_iused + 1000))
19193
19194         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19195                         osp.*OST0000*MDT0000.create_count")
19196         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19197                                 osp.*OST0000*MDT0000.max_create_count")
19198         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19199
19200         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19201         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19202         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19203
19204         unlinkmany $DIR/$tdir/$tfile. 1000
19205
19206         do_nodes $mdts "$LCTL set_param -n \
19207                         osp.*OST0000*.max_create_count=$max_count"
19208         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19209                 do_nodes $mdts "$LCTL set_param -n \
19210                                 osp.*OST0000*.create_count=$count"
19211         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19212                         grep "=0" && error "create_count is zero"
19213
19214         local new_iused
19215         for i in $(seq 120); do
19216                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19217                 # system may be too busy to destroy all objs in time, use
19218                 # a somewhat small value to not fail autotest
19219                 [ $((old_iused - new_iused)) -gt 400 ] && break
19220                 sleep 1
19221         done
19222
19223         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19224         [ $((old_iused - new_iused)) -gt 400 ] ||
19225                 error "objs not destroyed after unlink"
19226 }
19227 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19228
19229 zfs_oid_to_objid()
19230 {
19231         local ost=$1
19232         local objid=$2
19233
19234         local vdevdir=$(dirname $(facet_vdevice $ost))
19235         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19236         local zfs_zapid=$(do_facet $ost $cmd |
19237                           grep -w "/O/0/d$((objid%32))" -C 5 |
19238                           awk '/Object/{getline; print $1}')
19239         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19240                           awk "/$objid = /"'{printf $3}')
19241
19242         echo $zfs_objid
19243 }
19244
19245 zfs_object_blksz() {
19246         local ost=$1
19247         local objid=$2
19248
19249         local vdevdir=$(dirname $(facet_vdevice $ost))
19250         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19251         local blksz=$(do_facet $ost $cmd $objid |
19252                       awk '/dblk/{getline; printf $4}')
19253
19254         case "${blksz: -1}" in
19255                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19256                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19257                 *) ;;
19258         esac
19259
19260         echo $blksz
19261 }
19262
19263 test_312() { # LU-4856
19264         remote_ost_nodsh && skip "remote OST with nodsh"
19265         [ "$ost1_FSTYPE" = "zfs" ] ||
19266                 skip_env "the test only applies to zfs"
19267
19268         local max_blksz=$(do_facet ost1 \
19269                           $ZFS get -p recordsize $(facet_device ost1) |
19270                           awk '!/VALUE/{print $3}')
19271
19272         # to make life a little bit easier
19273         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19274         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19275
19276         local tf=$DIR/$tdir/$tfile
19277         touch $tf
19278         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19279
19280         # Get ZFS object id
19281         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19282         # block size change by sequential overwrite
19283         local bs
19284
19285         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19286                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19287
19288                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19289                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19290         done
19291         rm -f $tf
19292
19293         # block size change by sequential append write
19294         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19295         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19296         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19297         local count
19298
19299         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19300                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19301                         oflag=sync conv=notrunc
19302
19303                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19304                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19305                         error "blksz error, actual $blksz, " \
19306                                 "expected: 2 * $count * $PAGE_SIZE"
19307         done
19308         rm -f $tf
19309
19310         # random write
19311         touch $tf
19312         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19313         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19314
19315         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19316         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19317         [ $blksz -eq $PAGE_SIZE ] ||
19318                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19319
19320         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19321         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19322         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19323
19324         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19325         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19326         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19327 }
19328 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19329
19330 test_313() {
19331         remote_ost_nodsh && skip "remote OST with nodsh"
19332
19333         local file=$DIR/$tfile
19334
19335         rm -f $file
19336         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19337
19338         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19339         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19340         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19341                 error "write should failed"
19342         do_facet ost1 "$LCTL set_param fail_loc=0"
19343         rm -f $file
19344 }
19345 run_test 313 "io should fail after last_rcvd update fail"
19346
19347 test_314() {
19348         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19349
19350         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19351         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19352         rm -f $DIR/$tfile
19353         wait_delete_completed
19354         do_facet ost1 "$LCTL set_param fail_loc=0"
19355 }
19356 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19357
19358 test_315() { # LU-618
19359         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19360
19361         local file=$DIR/$tfile
19362         rm -f $file
19363
19364         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19365                 error "multiop file write failed"
19366         $MULTIOP $file oO_RDONLY:r4063232_c &
19367         PID=$!
19368
19369         sleep 2
19370
19371         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19372         kill -USR1 $PID
19373
19374         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19375         rm -f $file
19376 }
19377 run_test 315 "read should be accounted"
19378
19379 test_316() {
19380         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19381         large_xattr_enabled || skip_env "ea_inode feature disabled"
19382
19383         rm -rf $DIR/$tdir/d
19384         mkdir -p $DIR/$tdir/d
19385         chown nobody $DIR/$tdir/d
19386         touch $DIR/$tdir/d/file
19387
19388         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19389 }
19390 run_test 316 "lfs mv"
19391
19392 test_317() {
19393         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19394                 skip "Need MDS version at least 2.11.53"
19395         if [ "$ost1_FSTYPE" == "zfs" ]; then
19396                 skip "LU-10370: no implementation for ZFS"
19397         fi
19398
19399         local trunc_sz
19400         local grant_blk_size
19401
19402         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19403                         awk '/grant_block_size:/ { print $2; exit; }')
19404         #
19405         # Create File of size 5M. Truncate it to below size's and verify
19406         # blocks count.
19407         #
19408         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19409                 error "Create file $DIR/$tfile failed"
19410         stack_trap "rm -f $DIR/$tfile" EXIT
19411
19412         for trunc_sz in 2097152 4097 4000 509 0; do
19413                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19414                         error "truncate $tfile to $trunc_sz failed"
19415                 local sz=$(stat --format=%s $DIR/$tfile)
19416                 local blk=$(stat --format=%b $DIR/$tfile)
19417                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19418                                      grant_blk_size) * 8))
19419
19420                 if [[ $blk -ne $trunc_blk ]]; then
19421                         $(which stat) $DIR/$tfile
19422                         error "Expected Block $trunc_blk got $blk for $tfile"
19423                 fi
19424
19425                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19426                         error "Expected Size $trunc_sz got $sz for $tfile"
19427         done
19428
19429         #
19430         # sparse file test
19431         # Create file with a hole and write actual two blocks. Block count
19432         # must be 16.
19433         #
19434         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19435                 conv=fsync || error "Create file : $DIR/$tfile"
19436
19437         # Calculate the final truncate size.
19438         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19439
19440         #
19441         # truncate to size $trunc_sz bytes. Strip the last block
19442         # The block count must drop to 8
19443         #
19444         $TRUNCATE $DIR/$tfile $trunc_sz ||
19445                 error "truncate $tfile to $trunc_sz failed"
19446
19447         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19448         sz=$(stat --format=%s $DIR/$tfile)
19449         blk=$(stat --format=%b $DIR/$tfile)
19450
19451         if [[ $blk -ne $trunc_bsz ]]; then
19452                 $(which stat) $DIR/$tfile
19453                 error "Expected Block $trunc_bsz got $blk for $tfile"
19454         fi
19455
19456         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19457                 error "Expected Size $trunc_sz got $sz for $tfile"
19458 }
19459 run_test 317 "Verify blocks get correctly update after truncate"
19460
19461 test_318() {
19462         local old_max_active=$($LCTL get_param -n \
19463                             llite.*.max_read_ahead_async_active 2>/dev/null)
19464
19465         $LCTL set_param llite.*.max_read_ahead_async_active=256
19466         local max_active=$($LCTL get_param -n \
19467                            llite.*.max_read_ahead_async_active 2>/dev/null)
19468         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19469
19470         # currently reset to 0 is unsupported, leave it 512 for now.
19471         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19472                 error "set max_read_ahead_async_active should fail"
19473
19474         $LCTL set_param llite.*.max_read_ahead_async_active=512
19475         max_active=$($LCTL get_param -n \
19476                      llite.*.max_read_ahead_async_active 2>/dev/null)
19477         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19478
19479         # restore @max_active
19480         [ $old_max_active -ne 0 ] && $LCTL set_param \
19481                 llite.*.max_read_ahead_async_active=$old_max_active
19482
19483         local old_threshold=$($LCTL get_param -n \
19484                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19485         local max_per_file_mb=$($LCTL get_param -n \
19486                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19487
19488         local invalid=$(($max_per_file_mb + 1))
19489         $LCTL set_param \
19490                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19491                         && error "set $invalid should fail"
19492
19493         local valid=$(($invalid - 1))
19494         $LCTL set_param \
19495                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19496                         error "set $valid should succeed"
19497         local threshold=$($LCTL get_param -n \
19498                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19499         [ $threshold -eq $valid ] || error \
19500                 "expect threshold $valid got $threshold"
19501         $LCTL set_param \
19502                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19503 }
19504 run_test 318 "Verify async readahead tunables"
19505
19506 test_319() {
19507         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19508
19509         local before=$(date +%s)
19510         local evict
19511         local mdir=$DIR/$tdir
19512         local file=$mdir/xxx
19513
19514         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19515         touch $file
19516
19517 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19518         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19519         $LFS mv -m1 $file &
19520
19521         sleep 1
19522         dd if=$file of=/dev/null
19523         wait
19524         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19525           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19526
19527         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19528 }
19529 run_test 319 "lost lease lock on migrate error"
19530
19531 test_fake_rw() {
19532         local read_write=$1
19533         if [ "$read_write" = "write" ]; then
19534                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19535         elif [ "$read_write" = "read" ]; then
19536                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19537         else
19538                 error "argument error"
19539         fi
19540
19541         # turn off debug for performance testing
19542         local saved_debug=$($LCTL get_param -n debug)
19543         $LCTL set_param debug=0
19544
19545         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19546
19547         # get ost1 size - lustre-OST0000
19548         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19549         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19550         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19551
19552         if [ "$read_write" = "read" ]; then
19553                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19554         fi
19555
19556         local start_time=$(date +%s.%N)
19557         $dd_cmd bs=1M count=$blocks oflag=sync ||
19558                 error "real dd $read_write error"
19559         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19560
19561         if [ "$read_write" = "write" ]; then
19562                 rm -f $DIR/$tfile
19563         fi
19564
19565         # define OBD_FAIL_OST_FAKE_RW           0x238
19566         do_facet ost1 $LCTL set_param fail_loc=0x238
19567
19568         local start_time=$(date +%s.%N)
19569         $dd_cmd bs=1M count=$blocks oflag=sync ||
19570                 error "fake dd $read_write error"
19571         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19572
19573         if [ "$read_write" = "write" ]; then
19574                 # verify file size
19575                 cancel_lru_locks osc
19576                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19577                         error "$tfile size not $blocks MB"
19578         fi
19579         do_facet ost1 $LCTL set_param fail_loc=0
19580
19581         echo "fake $read_write $duration_fake vs. normal $read_write" \
19582                 "$duration in seconds"
19583         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19584                 error_not_in_vm "fake write is slower"
19585
19586         $LCTL set_param -n debug="$saved_debug"
19587         rm -f $DIR/$tfile
19588 }
19589 test_399a() { # LU-7655 for OST fake write
19590         remote_ost_nodsh && skip "remote OST with nodsh"
19591
19592         test_fake_rw write
19593 }
19594 run_test 399a "fake write should not be slower than normal write"
19595
19596 test_399b() { # LU-8726 for OST fake read
19597         remote_ost_nodsh && skip "remote OST with nodsh"
19598         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19599                 skip_env "ldiskfs only test"
19600         fi
19601
19602         test_fake_rw read
19603 }
19604 run_test 399b "fake read should not be slower than normal read"
19605
19606 test_400a() { # LU-1606, was conf-sanity test_74
19607         if ! which $CC > /dev/null 2>&1; then
19608                 skip_env "$CC is not installed"
19609         fi
19610
19611         local extra_flags=''
19612         local out=$TMP/$tfile
19613         local prefix=/usr/include/lustre
19614         local prog
19615
19616         if ! [[ -d $prefix ]]; then
19617                 # Assume we're running in tree and fixup the include path.
19618                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19619                 extra_flags+=" -L$LUSTRE/utils/.lib"
19620         fi
19621
19622         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19623                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19624                         error "client api broken"
19625         done
19626         rm -f $out
19627 }
19628 run_test 400a "Lustre client api program can compile and link"
19629
19630 test_400b() { # LU-1606, LU-5011
19631         local header
19632         local out=$TMP/$tfile
19633         local prefix=/usr/include/linux/lustre
19634
19635         # We use a hard coded prefix so that this test will not fail
19636         # when run in tree. There are headers in lustre/include/lustre/
19637         # that are not packaged (like lustre_idl.h) and have more
19638         # complicated include dependencies (like config.h and lnet/types.h).
19639         # Since this test about correct packaging we just skip them when
19640         # they don't exist (see below) rather than try to fixup cppflags.
19641
19642         if ! which $CC > /dev/null 2>&1; then
19643                 skip_env "$CC is not installed"
19644         fi
19645
19646         for header in $prefix/*.h; do
19647                 if ! [[ -f "$header" ]]; then
19648                         continue
19649                 fi
19650
19651                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19652                         continue # lustre_ioctl.h is internal header
19653                 fi
19654
19655                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19656                         error "cannot compile '$header'"
19657         done
19658         rm -f $out
19659 }
19660 run_test 400b "packaged headers can be compiled"
19661
19662 test_401a() { #LU-7437
19663         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19664         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19665
19666         #count the number of parameters by "list_param -R"
19667         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19668         #count the number of parameters by listing proc files
19669         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19670         echo "proc_dirs='$proc_dirs'"
19671         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19672         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19673                       sort -u | wc -l)
19674
19675         [ $params -eq $procs ] ||
19676                 error "found $params parameters vs. $procs proc files"
19677
19678         # test the list_param -D option only returns directories
19679         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19680         #count the number of parameters by listing proc directories
19681         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19682                 sort -u | wc -l)
19683
19684         [ $params -eq $procs ] ||
19685                 error "found $params parameters vs. $procs proc files"
19686 }
19687 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19688
19689 test_401b() {
19690         local save=$($LCTL get_param -n jobid_var)
19691         local tmp=testing
19692
19693         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19694                 error "no error returned when setting bad parameters"
19695
19696         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19697         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19698
19699         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19700         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19701         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19702 }
19703 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19704
19705 test_401c() {
19706         local jobid_var_old=$($LCTL get_param -n jobid_var)
19707         local jobid_var_new
19708
19709         $LCTL set_param jobid_var= &&
19710                 error "no error returned for 'set_param a='"
19711
19712         jobid_var_new=$($LCTL get_param -n jobid_var)
19713         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19714                 error "jobid_var was changed by setting without value"
19715
19716         $LCTL set_param jobid_var &&
19717                 error "no error returned for 'set_param a'"
19718
19719         jobid_var_new=$($LCTL get_param -n jobid_var)
19720         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19721                 error "jobid_var was changed by setting without value"
19722 }
19723 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19724
19725 test_401d() {
19726         local jobid_var_old=$($LCTL get_param -n jobid_var)
19727         local jobid_var_new
19728         local new_value="foo=bar"
19729
19730         $LCTL set_param jobid_var=$new_value ||
19731                 error "'set_param a=b' did not accept a value containing '='"
19732
19733         jobid_var_new=$($LCTL get_param -n jobid_var)
19734         [[ "$jobid_var_new" == "$new_value" ]] ||
19735                 error "'set_param a=b' failed on a value containing '='"
19736
19737         # Reset the jobid_var to test the other format
19738         $LCTL set_param jobid_var=$jobid_var_old
19739         jobid_var_new=$($LCTL get_param -n jobid_var)
19740         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19741                 error "failed to reset jobid_var"
19742
19743         $LCTL set_param jobid_var $new_value ||
19744                 error "'set_param a b' did not accept a value containing '='"
19745
19746         jobid_var_new=$($LCTL get_param -n jobid_var)
19747         [[ "$jobid_var_new" == "$new_value" ]] ||
19748                 error "'set_param a b' failed on a value containing '='"
19749
19750         $LCTL set_param jobid_var $jobid_var_old
19751         jobid_var_new=$($LCTL get_param -n jobid_var)
19752         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19753                 error "failed to reset jobid_var"
19754 }
19755 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19756
19757 test_402() {
19758         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19759         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19760                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19761         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19762                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19763                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19764         remote_mds_nodsh && skip "remote MDS with nodsh"
19765
19766         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19767 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19768         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19769         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19770                 echo "Touch failed - OK"
19771 }
19772 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19773
19774 test_403() {
19775         local file1=$DIR/$tfile.1
19776         local file2=$DIR/$tfile.2
19777         local tfile=$TMP/$tfile
19778
19779         rm -f $file1 $file2 $tfile
19780
19781         touch $file1
19782         ln $file1 $file2
19783
19784         # 30 sec OBD_TIMEOUT in ll_getattr()
19785         # right before populating st_nlink
19786         $LCTL set_param fail_loc=0x80001409
19787         stat -c %h $file1 > $tfile &
19788
19789         # create an alias, drop all locks and reclaim the dentry
19790         < $file2
19791         cancel_lru_locks mdc
19792         cancel_lru_locks osc
19793         sysctl -w vm.drop_caches=2
19794
19795         wait
19796
19797         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19798
19799         rm -f $tfile $file1 $file2
19800 }
19801 run_test 403 "i_nlink should not drop to zero due to aliasing"
19802
19803 test_404() { # LU-6601
19804         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19805                 skip "Need server version newer than 2.8.52"
19806         remote_mds_nodsh && skip "remote MDS with nodsh"
19807
19808         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19809                 awk '/osp .*-osc-MDT/ { print $4}')
19810
19811         local osp
19812         for osp in $mosps; do
19813                 echo "Deactivate: " $osp
19814                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19815                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19816                         awk -vp=$osp '$4 == p { print $2 }')
19817                 [ $stat = IN ] || {
19818                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19819                         error "deactivate error"
19820                 }
19821                 echo "Activate: " $osp
19822                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19823                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19824                         awk -vp=$osp '$4 == p { print $2 }')
19825                 [ $stat = UP ] || {
19826                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19827                         error "activate error"
19828                 }
19829         done
19830 }
19831 run_test 404 "validate manual {de}activated works properly for OSPs"
19832
19833 test_405() {
19834         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19835         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19836                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19837                         skip "Layout swap lock is not supported"
19838
19839         check_swap_layouts_support
19840
19841         test_mkdir $DIR/$tdir
19842         swap_lock_test -d $DIR/$tdir ||
19843                 error "One layout swap locked test failed"
19844 }
19845 run_test 405 "Various layout swap lock tests"
19846
19847 test_406() {
19848         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19849         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19850         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19851         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19852         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19853                 skip "Need MDS version at least 2.8.50"
19854
19855         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19856         local test_pool=$TESTNAME
19857
19858         if ! combined_mgs_mds ; then
19859                 mount_mgs_client
19860         fi
19861         pool_add $test_pool || error "pool_add failed"
19862         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19863                 error "pool_add_targets failed"
19864
19865         save_layout_restore_at_exit $MOUNT
19866
19867         # parent set default stripe count only, child will stripe from both
19868         # parent and fs default
19869         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19870                 error "setstripe $MOUNT failed"
19871         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19872         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19873         for i in $(seq 10); do
19874                 local f=$DIR/$tdir/$tfile.$i
19875                 touch $f || error "touch failed"
19876                 local count=$($LFS getstripe -c $f)
19877                 [ $count -eq $OSTCOUNT ] ||
19878                         error "$f stripe count $count != $OSTCOUNT"
19879                 local offset=$($LFS getstripe -i $f)
19880                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19881                 local size=$($LFS getstripe -S $f)
19882                 [ $size -eq $((def_stripe_size * 2)) ] ||
19883                         error "$f stripe size $size != $((def_stripe_size * 2))"
19884                 local pool=$($LFS getstripe -p $f)
19885                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19886         done
19887
19888         # change fs default striping, delete parent default striping, now child
19889         # will stripe from new fs default striping only
19890         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19891                 error "change $MOUNT default stripe failed"
19892         $LFS setstripe -c 0 $DIR/$tdir ||
19893                 error "delete $tdir default stripe failed"
19894         for i in $(seq 11 20); do
19895                 local f=$DIR/$tdir/$tfile.$i
19896                 touch $f || error "touch $f failed"
19897                 local count=$($LFS getstripe -c $f)
19898                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19899                 local offset=$($LFS getstripe -i $f)
19900                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19901                 local size=$($LFS getstripe -S $f)
19902                 [ $size -eq $def_stripe_size ] ||
19903                         error "$f stripe size $size != $def_stripe_size"
19904                 local pool=$($LFS getstripe -p $f)
19905                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19906         done
19907
19908         unlinkmany $DIR/$tdir/$tfile. 1 20
19909
19910         local f=$DIR/$tdir/$tfile
19911         pool_remove_all_targets $test_pool $f
19912         pool_remove $test_pool $f
19913
19914         if ! combined_mgs_mds ; then
19915                 umount_mgs_client
19916         fi
19917 }
19918 run_test 406 "DNE support fs default striping"
19919
19920 test_407() {
19921         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19922         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19923                 skip "Need MDS version at least 2.8.55"
19924         remote_mds_nodsh && skip "remote MDS with nodsh"
19925
19926         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19927                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19928         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19929                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19930         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19931
19932         #define OBD_FAIL_DT_TXN_STOP    0x2019
19933         for idx in $(seq $MDSCOUNT); do
19934                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19935         done
19936         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19937         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19938                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19939         true
19940 }
19941 run_test 407 "transaction fail should cause operation fail"
19942
19943 test_408() {
19944         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19945
19946         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19947         lctl set_param fail_loc=0x8000040a
19948         # let ll_prepare_partial_page() fail
19949         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19950
19951         rm -f $DIR/$tfile
19952
19953         # create at least 100 unused inodes so that
19954         # shrink_icache_memory(0) should not return 0
19955         touch $DIR/$tfile-{0..100}
19956         rm -f $DIR/$tfile-{0..100}
19957         sync
19958
19959         echo 2 > /proc/sys/vm/drop_caches
19960 }
19961 run_test 408 "drop_caches should not hang due to page leaks"
19962
19963 test_409()
19964 {
19965         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19966
19967         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19968         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19969         touch $DIR/$tdir/guard || error "(2) Fail to create"
19970
19971         local PREFIX=$(str_repeat 'A' 128)
19972         echo "Create 1K hard links start at $(date)"
19973         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19974                 error "(3) Fail to hard link"
19975
19976         echo "Links count should be right although linkEA overflow"
19977         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19978         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19979         [ $linkcount -eq 1001 ] ||
19980                 error "(5) Unexpected hard links count: $linkcount"
19981
19982         echo "List all links start at $(date)"
19983         ls -l $DIR/$tdir/foo > /dev/null ||
19984                 error "(6) Fail to list $DIR/$tdir/foo"
19985
19986         echo "Unlink hard links start at $(date)"
19987         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19988                 error "(7) Fail to unlink"
19989         echo "Unlink hard links finished at $(date)"
19990 }
19991 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19992
19993 test_410()
19994 {
19995         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19996                 skip "Need client version at least 2.9.59"
19997
19998         # Create a file, and stat it from the kernel
19999         local testfile=$DIR/$tfile
20000         touch $testfile
20001
20002         local run_id=$RANDOM
20003         local my_ino=$(stat --format "%i" $testfile)
20004
20005         # Try to insert the module. This will always fail as the
20006         # module is designed to not be inserted.
20007         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20008             &> /dev/null
20009
20010         # Anything but success is a test failure
20011         dmesg | grep -q \
20012             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20013             error "no inode match"
20014 }
20015 run_test 410 "Test inode number returned from kernel thread"
20016
20017 cleanup_test411_cgroup() {
20018         trap 0
20019         rmdir "$1"
20020 }
20021
20022 test_411() {
20023         local cg_basedir=/sys/fs/cgroup/memory
20024         # LU-9966
20025         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20026                 skip "no setup for cgroup"
20027
20028         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20029                 error "test file creation failed"
20030         cancel_lru_locks osc
20031
20032         # Create a very small memory cgroup to force a slab allocation error
20033         local cgdir=$cg_basedir/osc_slab_alloc
20034         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20035         trap "cleanup_test411_cgroup $cgdir" EXIT
20036         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20037         echo 1M > $cgdir/memory.limit_in_bytes
20038
20039         # Should not LBUG, just be killed by oom-killer
20040         # dd will return 0 even allocation failure in some environment.
20041         # So don't check return value
20042         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20043         cleanup_test411_cgroup $cgdir
20044
20045         return 0
20046 }
20047 run_test 411 "Slab allocation error with cgroup does not LBUG"
20048
20049 test_412() {
20050         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20051         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20052                 skip "Need server version at least 2.10.55"
20053         fi
20054
20055         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20056                 error "mkdir failed"
20057         $LFS getdirstripe $DIR/$tdir
20058         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20059         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20060                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20061         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20062         [ $stripe_count -eq 2 ] ||
20063                 error "expect 2 get $stripe_count"
20064 }
20065 run_test 412 "mkdir on specific MDTs"
20066
20067 test_413a() {
20068         [ $MDSCOUNT -lt 2 ] &&
20069                 skip "We need at least 2 MDTs for this test"
20070
20071         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20072                 skip "Need server version at least 2.10.55"
20073         fi
20074
20075         mkdir $DIR/$tdir || error "mkdir failed"
20076
20077         # find MDT that is the most full
20078         local max=$($LFS df | grep MDT |
20079                 awk 'BEGIN { a=0 }
20080                         { sub("%", "", $5)
20081                           if (0+$5 >= a)
20082                           {
20083                                 a = $5
20084                                 b = $6
20085                           }
20086                         }
20087                      END { split(b, c, ":")
20088                            sub("]", "", c[2])
20089                            print c[2]
20090                          }')
20091
20092         for i in $(seq $((MDSCOUNT - 1))); do
20093                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20094                         error "mkdir d$i failed"
20095                 $LFS getdirstripe $DIR/$tdir/d$i
20096                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20097                 [ $stripe_index -ne $max ] ||
20098                         error "don't expect $max"
20099         done
20100 }
20101 run_test 413a "mkdir on less full MDTs"
20102
20103 test_413b() {
20104         [ $MDSCOUNT -lt 2 ] &&
20105                 skip "We need at least 2 MDTs for this test"
20106
20107         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20108                 skip "Need server version at least 2.12.52"
20109
20110         mkdir $DIR/$tdir || error "mkdir failed"
20111         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20112                 error "setdirstripe failed"
20113
20114         local qos_prio_free
20115         local qos_threshold_rr
20116         local count
20117
20118         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20119         qos_prio_free=${qos_prio_free%%%}
20120         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20121         qos_threshold_rr=${qos_threshold_rr%%%}
20122         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20123
20124         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20125         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20126                 EXIT
20127         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20128
20129         echo "mkdir with roundrobin"
20130
20131         $LCTL set_param lmv.*.qos_threshold_rr=100
20132         for i in $(seq $((100 * MDSCOUNT))); do
20133                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20134         done
20135         for i in $(seq $MDSCOUNT); do
20136                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20137                         wc -w)
20138                 echo "$count directories created on MDT$((i - 1))"
20139                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20140         done
20141
20142         rm -rf $DIR/$tdir/*
20143
20144         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20145         # Shorten statfs result age, so that it can be updated in time
20146         $LCTL set_param lmv.*.qos_maxage=1
20147         sleep_maxage
20148
20149         local ffree
20150         local max
20151         local min
20152         local max_index
20153         local min_index
20154
20155         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20156         echo "MDT filesfree available: ${ffree[@]}"
20157         max=${ffree[0]}
20158         min=${ffree[0]}
20159         max_index=0
20160         min_index=0
20161         for ((i = 0; i < ${#ffree[@]}; i++)); do
20162                 if [[ ${ffree[i]} -gt $max ]]; then
20163                         max=${ffree[i]}
20164                         max_index=$i
20165                 fi
20166                 if [[ ${ffree[i]} -lt $min ]]; then
20167                         min=${ffree[i]}
20168                         min_index=$i
20169                 fi
20170         done
20171         echo "Min free files: MDT$min_index: $min"
20172         echo "Max free files: MDT$max_index: $max"
20173
20174         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20175         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20176
20177         # Check if we need to generate uneven MDTs
20178         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20179         local threshold=10
20180         local diff=$((max - min))
20181         local diff2=$((diff * 100 / min))
20182
20183         echo -n "Check for uneven MDTs: "
20184         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20185
20186         if [ $diff2 -gt $threshold ]; then
20187                 echo "ok"
20188                 echo "Don't need to fill MDT$min_index"
20189         else
20190                 # generate uneven MDTs, create till 25% diff
20191                 echo "no"
20192                 diff2=$((threshold - diff2))
20193                 diff=$((min * diff2 / 100))
20194                 # 50 sec per 10000 files in vm
20195                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20196                         skip "$diff files to create"
20197                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20198                 local i
20199                 local value="$(generate_string 1024)"
20200                 for i in $(seq $diff); do
20201                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20202                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20203                                 error "create f$i failed"
20204                         setfattr -n user.413b -v $value \
20205                                 $DIR/$tdir-MDT$min_index/f$i ||
20206                                 error "setfattr f$i failed"
20207                 done
20208         fi
20209
20210         min=$((100 *MDSCOUNT))
20211         max=0
20212
20213         echo "mkdir with balanced space usage"
20214         $LCTL set_param lmv.*.qos_prio_free=100
20215         for i in $(seq $((100 * MDSCOUNT))); do
20216                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20217         done
20218         for i in $(seq $MDSCOUNT); do
20219                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20220                         wc -w)
20221                 echo "$count directories created on MDT$((i - 1))"
20222                 [ $min -gt $count ] && min=$count
20223                 [ $max -lt $count ] && max=$count
20224         done
20225         [ $((max - min)) -gt $MDSCOUNT ] ||
20226                 error "subdirs shouldn't be evenly distributed"
20227
20228         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20229
20230         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20231         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20232         true
20233 }
20234 run_test 413b "mkdir with balanced space usage"
20235
20236 test_414() {
20237 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20238         $LCTL set_param fail_loc=0x80000521
20239         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20240         rm -f $DIR/$tfile
20241 }
20242 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20243
20244 test_415() {
20245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20246         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20247                 skip "Need server version at least 2.11.52"
20248
20249         # LU-11102
20250         local total
20251         local setattr_pid
20252         local start_time
20253         local end_time
20254         local duration
20255
20256         total=500
20257         # this test may be slow on ZFS
20258         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20259
20260         # though this test is designed for striped directory, let's test normal
20261         # directory too since lock is always saved as CoS lock.
20262         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20263         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20264
20265         (
20266                 while true; do
20267                         touch $DIR/$tdir
20268                 done
20269         ) &
20270         setattr_pid=$!
20271
20272         start_time=$(date +%s)
20273         for i in $(seq $total); do
20274                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20275                         > /dev/null
20276         done
20277         end_time=$(date +%s)
20278         duration=$((end_time - start_time))
20279
20280         kill -9 $setattr_pid
20281
20282         echo "rename $total files took $duration sec"
20283         [ $duration -lt 100 ] || error "rename took $duration sec"
20284 }
20285 run_test 415 "lock revoke is not missing"
20286
20287 test_416() {
20288         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20289                 skip "Need server version at least 2.11.55"
20290
20291         # define OBD_FAIL_OSD_TXN_START    0x19a
20292         do_facet mds1 lctl set_param fail_loc=0x19a
20293
20294         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20295
20296         true
20297 }
20298 run_test 416 "transaction start failure won't cause system hung"
20299
20300 cleanup_417() {
20301         trap 0
20302         do_nodes $(comma_list $(mdts_nodes)) \
20303                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20304         do_nodes $(comma_list $(mdts_nodes)) \
20305                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20306         do_nodes $(comma_list $(mdts_nodes)) \
20307                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20308 }
20309
20310 test_417() {
20311         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20312         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20313                 skip "Need MDS version at least 2.11.56"
20314
20315         trap cleanup_417 RETURN EXIT
20316
20317         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20318         do_nodes $(comma_list $(mdts_nodes)) \
20319                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20320         $LFS migrate -m 0 $DIR/$tdir.1 &&
20321                 error "migrate dir $tdir.1 should fail"
20322
20323         do_nodes $(comma_list $(mdts_nodes)) \
20324                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20325         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20326                 error "create remote dir $tdir.2 should fail"
20327
20328         do_nodes $(comma_list $(mdts_nodes)) \
20329                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20330         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20331                 error "create striped dir $tdir.3 should fail"
20332         true
20333 }
20334 run_test 417 "disable remote dir, striped dir and dir migration"
20335
20336 # Checks that the outputs of df [-i] and lfs df [-i] match
20337 #
20338 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20339 check_lfs_df() {
20340         local dir=$2
20341         local inodes
20342         local df_out
20343         local lfs_df_out
20344         local count
20345         local passed=false
20346
20347         # blocks or inodes
20348         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20349
20350         for count in {1..100}; do
20351                 cancel_lru_locks
20352                 sync; sleep 0.2
20353
20354                 # read the lines of interest
20355                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20356                         error "df $inodes $dir | tail -n +2 failed"
20357                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20358                         error "lfs df $inodes $dir | grep summary: failed"
20359
20360                 # skip first substrings of each output as they are different
20361                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20362                 # compare the two outputs
20363                 passed=true
20364                 for i in {1..5}; do
20365                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20366                 done
20367                 $passed && break
20368         done
20369
20370         if ! $passed; then
20371                 df -P $inodes $dir
20372                 echo
20373                 lfs df $inodes $dir
20374                 error "df and lfs df $1 output mismatch: "      \
20375                       "df ${inodes}: ${df_out[*]}, "            \
20376                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20377         fi
20378 }
20379
20380 test_418() {
20381         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20382
20383         local dir=$DIR/$tdir
20384         local numfiles=$((RANDOM % 4096 + 2))
20385         local numblocks=$((RANDOM % 256 + 1))
20386
20387         wait_delete_completed
20388         test_mkdir $dir
20389
20390         # check block output
20391         check_lfs_df blocks $dir
20392         # check inode output
20393         check_lfs_df inodes $dir
20394
20395         # create a single file and retest
20396         echo "Creating a single file and testing"
20397         createmany -o $dir/$tfile- 1 &>/dev/null ||
20398                 error "creating 1 file in $dir failed"
20399         check_lfs_df blocks $dir
20400         check_lfs_df inodes $dir
20401
20402         # create a random number of files
20403         echo "Creating $((numfiles - 1)) files and testing"
20404         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20405                 error "creating $((numfiles - 1)) files in $dir failed"
20406
20407         # write a random number of blocks to the first test file
20408         echo "Writing $numblocks 4K blocks and testing"
20409         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20410                 count=$numblocks &>/dev/null ||
20411                 error "dd to $dir/${tfile}-0 failed"
20412
20413         # retest
20414         check_lfs_df blocks $dir
20415         check_lfs_df inodes $dir
20416
20417         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20418                 error "unlinking $numfiles files in $dir failed"
20419 }
20420 run_test 418 "df and lfs df outputs match"
20421
20422 test_419()
20423 {
20424         local dir=$DIR/$tdir
20425
20426         mkdir -p $dir
20427         touch $dir/file
20428
20429         cancel_lru_locks mdc
20430
20431         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20432         $LCTL set_param fail_loc=0x1410
20433         cat $dir/file
20434         $LCTL set_param fail_loc=0
20435         rm -rf $dir
20436 }
20437 run_test 419 "Verify open file by name doesn't crash kernel"
20438
20439 test_420()
20440 {
20441         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20442                 skip "Need MDS version at least 2.12.53"
20443
20444         local SAVE_UMASK=$(umask)
20445         local dir=$DIR/$tdir
20446         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20447
20448         mkdir -p $dir
20449         umask 0000
20450         mkdir -m03777 $dir/testdir
20451         ls -dn $dir/testdir
20452         # Need to remove trailing '.' when SELinux is enabled
20453         local dirperms=$(ls -dn $dir/testdir |
20454                          awk '{ sub(/\.$/, "", $1); print $1}')
20455         [ $dirperms == "drwxrwsrwt" ] ||
20456                 error "incorrect perms on $dir/testdir"
20457
20458         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20459                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20460         ls -n $dir/testdir/testfile
20461         local fileperms=$(ls -n $dir/testdir/testfile |
20462                           awk '{ sub(/\.$/, "", $1); print $1}')
20463         [ $fileperms == "-rwxr-xr-x" ] ||
20464                 error "incorrect perms on $dir/testdir/testfile"
20465
20466         umask $SAVE_UMASK
20467 }
20468 run_test 420 "clear SGID bit on non-directories for non-members"
20469
20470 test_421a() {
20471         local cnt
20472         local fid1
20473         local fid2
20474
20475         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20476                 skip "Need MDS version at least 2.12.54"
20477
20478         test_mkdir $DIR/$tdir
20479         createmany -o $DIR/$tdir/f 3
20480         cnt=$(ls -1 $DIR/$tdir | wc -l)
20481         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20482
20483         fid1=$(lfs path2fid $DIR/$tdir/f1)
20484         fid2=$(lfs path2fid $DIR/$tdir/f2)
20485         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
20486
20487         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
20488         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
20489
20490         cnt=$(ls -1 $DIR/$tdir | wc -l)
20491         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20492
20493         rm -f $DIR/$tdir/f3 || error "can't remove f3"
20494         createmany -o $DIR/$tdir/f 3
20495         cnt=$(ls -1 $DIR/$tdir | wc -l)
20496         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20497
20498         fid1=$(lfs path2fid $DIR/$tdir/f1)
20499         fid2=$(lfs path2fid $DIR/$tdir/f2)
20500         echo "remove using fsname $FSNAME"
20501         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
20502
20503         cnt=$(ls -1 $DIR/$tdir | wc -l)
20504         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20505 }
20506 run_test 421a "simple rm by fid"
20507
20508 test_421b() {
20509         local cnt
20510         local FID1
20511         local FID2
20512
20513         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20514                 skip "Need MDS version at least 2.12.54"
20515
20516         test_mkdir $DIR/$tdir
20517         createmany -o $DIR/$tdir/f 3
20518         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
20519         MULTIPID=$!
20520
20521         FID1=$(lfs path2fid $DIR/$tdir/f1)
20522         FID2=$(lfs path2fid $DIR/$tdir/f2)
20523         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
20524
20525         kill -USR1 $MULTIPID
20526         wait
20527
20528         cnt=$(ls $DIR/$tdir | wc -l)
20529         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
20530 }
20531 run_test 421b "rm by fid on open file"
20532
20533 test_421c() {
20534         local cnt
20535         local FIDS
20536
20537         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20538                 skip "Need MDS version at least 2.12.54"
20539
20540         test_mkdir $DIR/$tdir
20541         createmany -o $DIR/$tdir/f 3
20542         touch $DIR/$tdir/$tfile
20543         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
20544         cnt=$(ls -1 $DIR/$tdir | wc -l)
20545         [ $cnt != 184 ] && error "unexpected #files: $cnt"
20546
20547         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
20548         $LFS rmfid $DIR $FID1 || error "rmfid failed"
20549
20550         cnt=$(ls $DIR/$tdir | wc -l)
20551         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
20552 }
20553 run_test 421c "rm by fid against hardlinked files"
20554
20555 test_421d() {
20556         local cnt
20557         local FIDS
20558
20559         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20560                 skip "Need MDS version at least 2.12.54"
20561
20562         test_mkdir $DIR/$tdir
20563         createmany -o $DIR/$tdir/f 4097
20564         cnt=$(ls -1 $DIR/$tdir | wc -l)
20565         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
20566
20567         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
20568         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20569
20570         cnt=$(ls $DIR/$tdir | wc -l)
20571         rm -rf $DIR/$tdir
20572         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20573 }
20574 run_test 421d "rmfid en masse"
20575
20576 test_421e() {
20577         local cnt
20578         local FID
20579
20580         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20581         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20582                 skip "Need MDS version at least 2.12.54"
20583
20584         mkdir -p $DIR/$tdir
20585         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20586         createmany -o $DIR/$tdir/striped_dir/f 512
20587         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20588         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20589
20590         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20591                 sed "s/[/][^:]*://g")
20592         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20593
20594         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20595         rm -rf $DIR/$tdir
20596         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20597 }
20598 run_test 421e "rmfid in DNE"
20599
20600 test_421f() {
20601         local cnt
20602         local FID
20603
20604         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20605                 skip "Need MDS version at least 2.12.54"
20606
20607         test_mkdir $DIR/$tdir
20608         touch $DIR/$tdir/f
20609         cnt=$(ls -1 $DIR/$tdir | wc -l)
20610         [ $cnt != 1 ] && error "unexpected #files: $cnt"
20611
20612         FID=$(lfs path2fid $DIR/$tdir/f)
20613         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
20614         # rmfid should fail
20615         cnt=$(ls -1 $DIR/$tdir | wc -l)
20616         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
20617
20618         chmod a+rw $DIR/$tdir
20619         ls -la $DIR/$tdir
20620         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
20621         # rmfid should fail
20622         cnt=$(ls -1 $DIR/$tdir | wc -l)
20623         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
20624
20625         rm -f $DIR/$tdir/f
20626         $RUNAS touch $DIR/$tdir/f
20627         FID=$(lfs path2fid $DIR/$tdir/f)
20628         echo "rmfid as root"
20629         $LFS rmfid $DIR $FID || error "rmfid as root failed"
20630         cnt=$(ls -1 $DIR/$tdir | wc -l)
20631         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
20632
20633         rm -f $DIR/$tdir/f
20634         $RUNAS touch $DIR/$tdir/f
20635         cnt=$(ls -1 $DIR/$tdir | wc -l)
20636         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
20637         FID=$(lfs path2fid $DIR/$tdir/f)
20638         # rmfid w/o user_fid2path mount option should fail
20639         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
20640         cnt=$(ls -1 $DIR/$tdir | wc -l)
20641         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
20642
20643         umount_client $MOUNT || "failed to umount client"
20644         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
20645                 "failed to mount client'"
20646
20647         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
20648         # rmfid should succeed
20649         cnt=$(ls -1 $DIR/$tdir | wc -l)
20650         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
20651
20652         # rmfid shouldn't allow to remove files due to dir's permission
20653         chmod a+rwx $DIR/$tdir
20654         touch $DIR/$tdir/f
20655         ls -la $DIR/$tdir
20656         FID=$(lfs path2fid $DIR/$tdir/f)
20657         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
20658
20659         umount_client $MOUNT || "failed to umount client"
20660         mount_client $MOUNT "$MOUNT_OPTS" ||
20661                 "failed to mount client'"
20662
20663 }
20664 run_test 421f "rmfid checks permissions"
20665
20666 test_421g() {
20667         local cnt
20668         local FIDS
20669
20670         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20671         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20672                 skip "Need MDS version at least 2.12.54"
20673
20674         mkdir -p $DIR/$tdir
20675         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20676         createmany -o $DIR/$tdir/striped_dir/f 512
20677         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20678         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20679
20680         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20681                 sed "s/[/][^:]*://g")
20682
20683         rm -f $DIR/$tdir/striped_dir/f1*
20684         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20685         removed=$((512 - cnt))
20686
20687         # few files have been just removed, so we expect
20688         # rmfid to fail on their fids
20689         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
20690         [ $removed != $errors ] && error "$errors != $removed"
20691
20692         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20693         rm -rf $DIR/$tdir
20694         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20695 }
20696 run_test 421g "rmfid to return errors properly"
20697
20698 prep_801() {
20699         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20700         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20701                 skip "Need server version at least 2.9.55"
20702
20703         start_full_debug_logging
20704 }
20705
20706 post_801() {
20707         stop_full_debug_logging
20708 }
20709
20710 barrier_stat() {
20711         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20712                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20713                            awk '/The barrier for/ { print $7 }')
20714                 echo $st
20715         else
20716                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20717                 echo \'$st\'
20718         fi
20719 }
20720
20721 barrier_expired() {
20722         local expired
20723
20724         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20725                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20726                           awk '/will be expired/ { print $7 }')
20727         else
20728                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20729         fi
20730
20731         echo $expired
20732 }
20733
20734 test_801a() {
20735         prep_801
20736
20737         echo "Start barrier_freeze at: $(date)"
20738         #define OBD_FAIL_BARRIER_DELAY          0x2202
20739         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20740         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20741
20742         sleep 2
20743         local b_status=$(barrier_stat)
20744         echo "Got barrier status at: $(date)"
20745         [ "$b_status" = "'freezing_p1'" ] ||
20746                 error "(1) unexpected barrier status $b_status"
20747
20748         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20749         wait
20750         b_status=$(barrier_stat)
20751         [ "$b_status" = "'frozen'" ] ||
20752                 error "(2) unexpected barrier status $b_status"
20753
20754         local expired=$(barrier_expired)
20755         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20756         sleep $((expired + 3))
20757
20758         b_status=$(barrier_stat)
20759         [ "$b_status" = "'expired'" ] ||
20760                 error "(3) unexpected barrier status $b_status"
20761
20762         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20763                 error "(4) fail to freeze barrier"
20764
20765         b_status=$(barrier_stat)
20766         [ "$b_status" = "'frozen'" ] ||
20767                 error "(5) unexpected barrier status $b_status"
20768
20769         echo "Start barrier_thaw at: $(date)"
20770         #define OBD_FAIL_BARRIER_DELAY          0x2202
20771         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20772         do_facet mgs $LCTL barrier_thaw $FSNAME &
20773
20774         sleep 2
20775         b_status=$(barrier_stat)
20776         echo "Got barrier status at: $(date)"
20777         [ "$b_status" = "'thawing'" ] ||
20778                 error "(6) unexpected barrier status $b_status"
20779
20780         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20781         wait
20782         b_status=$(barrier_stat)
20783         [ "$b_status" = "'thawed'" ] ||
20784                 error "(7) unexpected barrier status $b_status"
20785
20786         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20787         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20788         do_facet mgs $LCTL barrier_freeze $FSNAME
20789
20790         b_status=$(barrier_stat)
20791         [ "$b_status" = "'failed'" ] ||
20792                 error "(8) unexpected barrier status $b_status"
20793
20794         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20795         do_facet mgs $LCTL barrier_thaw $FSNAME
20796
20797         post_801
20798 }
20799 run_test 801a "write barrier user interfaces and stat machine"
20800
20801 test_801b() {
20802         prep_801
20803
20804         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20805         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20806         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20807         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20808         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20809
20810         cancel_lru_locks mdc
20811
20812         # 180 seconds should be long enough
20813         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20814
20815         local b_status=$(barrier_stat)
20816         [ "$b_status" = "'frozen'" ] ||
20817                 error "(6) unexpected barrier status $b_status"
20818
20819         mkdir $DIR/$tdir/d0/d10 &
20820         mkdir_pid=$!
20821
20822         touch $DIR/$tdir/d1/f13 &
20823         touch_pid=$!
20824
20825         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20826         ln_pid=$!
20827
20828         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20829         mv_pid=$!
20830
20831         rm -f $DIR/$tdir/d4/f12 &
20832         rm_pid=$!
20833
20834         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20835
20836         # To guarantee taht the 'stat' is not blocked
20837         b_status=$(barrier_stat)
20838         [ "$b_status" = "'frozen'" ] ||
20839                 error "(8) unexpected barrier status $b_status"
20840
20841         # let above commands to run at background
20842         sleep 5
20843
20844         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20845         ps -p $touch_pid || error "(10) touch should be blocked"
20846         ps -p $ln_pid || error "(11) link should be blocked"
20847         ps -p $mv_pid || error "(12) rename should be blocked"
20848         ps -p $rm_pid || error "(13) unlink should be blocked"
20849
20850         b_status=$(barrier_stat)
20851         [ "$b_status" = "'frozen'" ] ||
20852                 error "(14) unexpected barrier status $b_status"
20853
20854         do_facet mgs $LCTL barrier_thaw $FSNAME
20855         b_status=$(barrier_stat)
20856         [ "$b_status" = "'thawed'" ] ||
20857                 error "(15) unexpected barrier status $b_status"
20858
20859         wait $mkdir_pid || error "(16) mkdir should succeed"
20860         wait $touch_pid || error "(17) touch should succeed"
20861         wait $ln_pid || error "(18) link should succeed"
20862         wait $mv_pid || error "(19) rename should succeed"
20863         wait $rm_pid || error "(20) unlink should succeed"
20864
20865         post_801
20866 }
20867 run_test 801b "modification will be blocked by write barrier"
20868
20869 test_801c() {
20870         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20871
20872         prep_801
20873
20874         stop mds2 || error "(1) Fail to stop mds2"
20875
20876         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20877
20878         local b_status=$(barrier_stat)
20879         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20880                 do_facet mgs $LCTL barrier_thaw $FSNAME
20881                 error "(2) unexpected barrier status $b_status"
20882         }
20883
20884         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20885                 error "(3) Fail to rescan barrier bitmap"
20886
20887         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20888
20889         b_status=$(barrier_stat)
20890         [ "$b_status" = "'frozen'" ] ||
20891                 error "(4) unexpected barrier status $b_status"
20892
20893         do_facet mgs $LCTL barrier_thaw $FSNAME
20894         b_status=$(barrier_stat)
20895         [ "$b_status" = "'thawed'" ] ||
20896                 error "(5) unexpected barrier status $b_status"
20897
20898         local devname=$(mdsdevname 2)
20899
20900         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20901
20902         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20903                 error "(7) Fail to rescan barrier bitmap"
20904
20905         post_801
20906 }
20907 run_test 801c "rescan barrier bitmap"
20908
20909 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20910 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20911 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20912 saved_MOUNT_OPTS=$MOUNT_OPTS
20913
20914 cleanup_802a() {
20915         trap 0
20916
20917         stopall
20918         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20919         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20920         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20921         MOUNT_OPTS=$saved_MOUNT_OPTS
20922         setupall
20923 }
20924
20925 test_802a() {
20926
20927         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20928         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20929                 skip "Need server version at least 2.9.55"
20930
20931         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20932
20933         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20934
20935         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20936                 error "(2) Fail to copy"
20937
20938         trap cleanup_802a EXIT
20939
20940         # sync by force before remount as readonly
20941         sync; sync_all_data; sleep 3; sync_all_data
20942
20943         stopall
20944
20945         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20946         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20947         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20948
20949         echo "Mount the server as read only"
20950         setupall server_only || error "(3) Fail to start servers"
20951
20952         echo "Mount client without ro should fail"
20953         mount_client $MOUNT &&
20954                 error "(4) Mount client without 'ro' should fail"
20955
20956         echo "Mount client with ro should succeed"
20957         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
20958         mount_client $MOUNT ||
20959                 error "(5) Mount client with 'ro' should succeed"
20960
20961         echo "Modify should be refused"
20962         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20963
20964         echo "Read should be allowed"
20965         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20966                 error "(7) Read should succeed under ro mode"
20967
20968         cleanup_802a
20969 }
20970 run_test 802a "simulate readonly device"
20971
20972 test_802b() {
20973         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20974         remote_mds_nodsh && skip "remote MDS with nodsh"
20975
20976         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20977                 skip "readonly option not available"
20978
20979         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20980
20981         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20982                 error "(2) Fail to copy"
20983
20984         # write back all cached data before setting MDT to readonly
20985         cancel_lru_locks
20986         sync_all_data
20987
20988         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20989         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20990
20991         echo "Modify should be refused"
20992         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20993
20994         echo "Read should be allowed"
20995         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20996                 error "(7) Read should succeed under ro mode"
20997
20998         # disable readonly
20999         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21000 }
21001 run_test 802b "be able to set MDTs to readonly"
21002
21003 test_803() {
21004         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21005         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21006                 skip "MDS needs to be newer than 2.10.54"
21007
21008         mkdir -p $DIR/$tdir
21009         # Create some objects on all MDTs to trigger related logs objects
21010         for idx in $(seq $MDSCOUNT); do
21011                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21012                         $DIR/$tdir/dir${idx} ||
21013                         error "Fail to create $DIR/$tdir/dir${idx}"
21014         done
21015
21016         sync; sleep 3
21017         wait_delete_completed # ensure old test cleanups are finished
21018         echo "before create:"
21019         $LFS df -i $MOUNT
21020         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21021
21022         for i in {1..10}; do
21023                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21024                         error "Fail to create $DIR/$tdir/foo$i"
21025         done
21026
21027         sync; sleep 3
21028         echo "after create:"
21029         $LFS df -i $MOUNT
21030         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21031
21032         # allow for an llog to be cleaned up during the test
21033         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21034                 error "before ($before_used) + 10 > after ($after_used)"
21035
21036         for i in {1..10}; do
21037                 rm -rf $DIR/$tdir/foo$i ||
21038                         error "Fail to remove $DIR/$tdir/foo$i"
21039         done
21040
21041         sleep 3 # avoid MDT return cached statfs
21042         wait_delete_completed
21043         echo "after unlink:"
21044         $LFS df -i $MOUNT
21045         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21046
21047         # allow for an llog to be created during the test
21048         [ $after_used -le $((before_used + 1)) ] ||
21049                 error "after ($after_used) > before ($before_used) + 1"
21050 }
21051 run_test 803 "verify agent object for remote object"
21052
21053 test_804() {
21054         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21055         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21056                 skip "MDS needs to be newer than 2.10.54"
21057         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21058
21059         mkdir -p $DIR/$tdir
21060         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21061                 error "Fail to create $DIR/$tdir/dir0"
21062
21063         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21064         local dev=$(mdsdevname 2)
21065
21066         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21067                 grep ${fid} || error "NOT found agent entry for dir0"
21068
21069         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21070                 error "Fail to create $DIR/$tdir/dir1"
21071
21072         touch $DIR/$tdir/dir1/foo0 ||
21073                 error "Fail to create $DIR/$tdir/dir1/foo0"
21074         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21075         local rc=0
21076
21077         for idx in $(seq $MDSCOUNT); do
21078                 dev=$(mdsdevname $idx)
21079                 do_facet mds${idx} \
21080                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21081                         grep ${fid} && rc=$idx
21082         done
21083
21084         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21085                 error "Fail to rename foo0 to foo1"
21086         if [ $rc -eq 0 ]; then
21087                 for idx in $(seq $MDSCOUNT); do
21088                         dev=$(mdsdevname $idx)
21089                         do_facet mds${idx} \
21090                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21091                         grep ${fid} && rc=$idx
21092                 done
21093         fi
21094
21095         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21096                 error "Fail to rename foo1 to foo2"
21097         if [ $rc -eq 0 ]; then
21098                 for idx in $(seq $MDSCOUNT); do
21099                         dev=$(mdsdevname $idx)
21100                         do_facet mds${idx} \
21101                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21102                         grep ${fid} && rc=$idx
21103                 done
21104         fi
21105
21106         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21107
21108         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21109                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21110         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21111                 error "Fail to rename foo2 to foo0"
21112         unlink $DIR/$tdir/dir1/foo0 ||
21113                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21114         rm -rf $DIR/$tdir/dir0 ||
21115                 error "Fail to rm $DIR/$tdir/dir0"
21116
21117         for idx in $(seq $MDSCOUNT); do
21118                 dev=$(mdsdevname $idx)
21119                 rc=0
21120
21121                 stop mds${idx}
21122                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21123                         rc=$?
21124                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21125                         error "mount mds$idx failed"
21126                 df $MOUNT > /dev/null 2>&1
21127
21128                 # e2fsck should not return error
21129                 [ $rc -eq 0 ] ||
21130                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21131         done
21132 }
21133 run_test 804 "verify agent entry for remote entry"
21134
21135 cleanup_805() {
21136         do_facet $SINGLEMDS zfs set quota=$old $fsset
21137         unlinkmany $DIR/$tdir/f- 1000000
21138         trap 0
21139 }
21140
21141 test_805() {
21142         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21143         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21144         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21145                 skip "netfree not implemented before 0.7"
21146         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21147                 skip "Need MDS version at least 2.10.57"
21148
21149         local fsset
21150         local freekb
21151         local usedkb
21152         local old
21153         local quota
21154         local pref="osd-zfs.lustre-MDT0000."
21155
21156         # limit available space on MDS dataset to meet nospace issue
21157         # quickly. then ZFS 0.7.2 can use reserved space if asked
21158         # properly (using netfree flag in osd_declare_destroy()
21159         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21160         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21161                 gawk '{print $3}')
21162         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21163         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21164         let "usedkb=usedkb-freekb"
21165         let "freekb=freekb/2"
21166         if let "freekb > 5000"; then
21167                 let "freekb=5000"
21168         fi
21169         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21170         trap cleanup_805 EXIT
21171         mkdir $DIR/$tdir
21172         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21173         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21174         rm -rf $DIR/$tdir || error "not able to remove"
21175         do_facet $SINGLEMDS zfs set quota=$old $fsset
21176         trap 0
21177 }
21178 run_test 805 "ZFS can remove from full fs"
21179
21180 # Size-on-MDS test
21181 check_lsom_data()
21182 {
21183         local file=$1
21184         local size=$($LFS getsom -s $file)
21185         local expect=$(stat -c %s $file)
21186
21187         [[ $size == $expect ]] ||
21188                 error "$file expected size: $expect, got: $size"
21189
21190         local blocks=$($LFS getsom -b $file)
21191         expect=$(stat -c %b $file)
21192         [[ $blocks == $expect ]] ||
21193                 error "$file expected blocks: $expect, got: $blocks"
21194 }
21195
21196 check_lsom_size()
21197 {
21198         local size=$($LFS getsom -s $1)
21199         local expect=$2
21200
21201         [[ $size == $expect ]] ||
21202                 error "$file expected size: $expect, got: $size"
21203 }
21204
21205 test_806() {
21206         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21207                 skip "Need MDS version at least 2.11.52"
21208
21209         local bs=1048576
21210
21211         touch $DIR/$tfile || error "touch $tfile failed"
21212
21213         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21214         save_lustre_params client "llite.*.xattr_cache" > $save
21215         lctl set_param llite.*.xattr_cache=0
21216         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21217
21218         # single-threaded write
21219         echo "Test SOM for single-threaded write"
21220         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21221                 error "write $tfile failed"
21222         check_lsom_size $DIR/$tfile $bs
21223
21224         local num=32
21225         local size=$(($num * $bs))
21226         local offset=0
21227         local i
21228
21229         echo "Test SOM for single client multi-threaded($num) write"
21230         $TRUNCATE $DIR/$tfile 0
21231         for ((i = 0; i < $num; i++)); do
21232                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21233                 local pids[$i]=$!
21234                 offset=$((offset + $bs))
21235         done
21236         for (( i=0; i < $num; i++ )); do
21237                 wait ${pids[$i]}
21238         done
21239         check_lsom_size $DIR/$tfile $size
21240
21241         $TRUNCATE $DIR/$tfile 0
21242         for ((i = 0; i < $num; i++)); do
21243                 offset=$((offset - $bs))
21244                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21245                 local pids[$i]=$!
21246         done
21247         for (( i=0; i < $num; i++ )); do
21248                 wait ${pids[$i]}
21249         done
21250         check_lsom_size $DIR/$tfile $size
21251
21252         # multi-client wirtes
21253         num=$(get_node_count ${CLIENTS//,/ })
21254         size=$(($num * $bs))
21255         offset=0
21256         i=0
21257
21258         echo "Test SOM for multi-client ($num) writes"
21259         $TRUNCATE $DIR/$tfile 0
21260         for client in ${CLIENTS//,/ }; do
21261                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21262                 local pids[$i]=$!
21263                 i=$((i + 1))
21264                 offset=$((offset + $bs))
21265         done
21266         for (( i=0; i < $num; i++ )); do
21267                 wait ${pids[$i]}
21268         done
21269         check_lsom_size $DIR/$tfile $offset
21270
21271         i=0
21272         $TRUNCATE $DIR/$tfile 0
21273         for client in ${CLIENTS//,/ }; do
21274                 offset=$((offset - $bs))
21275                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21276                 local pids[$i]=$!
21277                 i=$((i + 1))
21278         done
21279         for (( i=0; i < $num; i++ )); do
21280                 wait ${pids[$i]}
21281         done
21282         check_lsom_size $DIR/$tfile $size
21283
21284         # verify truncate
21285         echo "Test SOM for truncate"
21286         $TRUNCATE $DIR/$tfile 1048576
21287         check_lsom_size $DIR/$tfile 1048576
21288         $TRUNCATE $DIR/$tfile 1234
21289         check_lsom_size $DIR/$tfile 1234
21290
21291         # verify SOM blocks count
21292         echo "Verify SOM block count"
21293         $TRUNCATE $DIR/$tfile 0
21294         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21295                 error "failed to write file $tfile"
21296         check_lsom_data $DIR/$tfile
21297 }
21298 run_test 806 "Verify Lazy Size on MDS"
21299
21300 test_807() {
21301         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21302         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21303                 skip "Need MDS version at least 2.11.52"
21304
21305         # Registration step
21306         changelog_register || error "changelog_register failed"
21307         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21308         changelog_users $SINGLEMDS | grep -q $cl_user ||
21309                 error "User $cl_user not found in changelog_users"
21310
21311         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21312         save_lustre_params client "llite.*.xattr_cache" > $save
21313         lctl set_param llite.*.xattr_cache=0
21314         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21315
21316         rm -rf $DIR/$tdir || error "rm $tdir failed"
21317         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21318         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21319         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21320         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21321                 error "truncate $tdir/trunc failed"
21322
21323         local bs=1048576
21324         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21325                 error "write $tfile failed"
21326
21327         # multi-client wirtes
21328         local num=$(get_node_count ${CLIENTS//,/ })
21329         local offset=0
21330         local i=0
21331
21332         echo "Test SOM for multi-client ($num) writes"
21333         touch $DIR/$tfile || error "touch $tfile failed"
21334         $TRUNCATE $DIR/$tfile 0
21335         for client in ${CLIENTS//,/ }; do
21336                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21337                 local pids[$i]=$!
21338                 i=$((i + 1))
21339                 offset=$((offset + $bs))
21340         done
21341         for (( i=0; i < $num; i++ )); do
21342                 wait ${pids[$i]}
21343         done
21344
21345         sleep 5
21346         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21347         check_lsom_data $DIR/$tdir/trunc
21348         check_lsom_data $DIR/$tdir/single_dd
21349         check_lsom_data $DIR/$tfile
21350
21351         rm -rf $DIR/$tdir
21352         # Deregistration step
21353         changelog_deregister || error "changelog_deregister failed"
21354 }
21355 run_test 807 "verify LSOM syncing tool"
21356
21357 check_som_nologged()
21358 {
21359         local lines=$($LFS changelog $FSNAME-MDT0000 |
21360                 grep 'x=trusted.som' | wc -l)
21361         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21362 }
21363
21364 test_808() {
21365         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21366                 skip "Need MDS version at least 2.11.55"
21367
21368         # Registration step
21369         changelog_register || error "changelog_register failed"
21370
21371         touch $DIR/$tfile || error "touch $tfile failed"
21372         check_som_nologged
21373
21374         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21375                 error "write $tfile failed"
21376         check_som_nologged
21377
21378         $TRUNCATE $DIR/$tfile 1234
21379         check_som_nologged
21380
21381         $TRUNCATE $DIR/$tfile 1048576
21382         check_som_nologged
21383
21384         # Deregistration step
21385         changelog_deregister || error "changelog_deregister failed"
21386 }
21387 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21388
21389 check_som_nodata()
21390 {
21391         $LFS getsom $1
21392         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21393 }
21394
21395 test_809() {
21396         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21397                 skip "Need MDS version at least 2.11.56"
21398
21399         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21400                 error "failed to create DoM-only file $DIR/$tfile"
21401         touch $DIR/$tfile || error "touch $tfile failed"
21402         check_som_nodata $DIR/$tfile
21403
21404         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21405                 error "write $tfile failed"
21406         check_som_nodata $DIR/$tfile
21407
21408         $TRUNCATE $DIR/$tfile 1234
21409         check_som_nodata $DIR/$tfile
21410
21411         $TRUNCATE $DIR/$tfile 4097
21412         check_som_nodata $DIR/$file
21413 }
21414 run_test 809 "Verify no SOM xattr store for DoM-only files"
21415
21416 test_810() {
21417         local ORIG
21418         local CSUM
21419
21420         # t10 seem to dislike partial pages
21421         lctl set_param osc.*.checksum_type=adler
21422         lctl set_param fail_loc=0x411
21423         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21424         ORIG=$(md5sum $DIR/$tfile)
21425         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21426         CSUM=$(md5sum $DIR/$tfile)
21427         set_checksum_type adler
21428         if [ "$ORIG" != "$CSUM" ]; then
21429                 error "$ORIG != $CSUM"
21430         fi
21431 }
21432 run_test 810 "partial page writes on ZFS (LU-11663)"
21433
21434 test_811() {
21435         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21436                 skip "Need MDS version at least 2.11.56"
21437
21438         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21439         do_facet mds1 $LCTL set_param fail_loc=0x165
21440         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21441
21442         stop mds1
21443         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21444
21445         sleep 5
21446         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21447                 error "MDD orphan cleanup thread not quit"
21448 }
21449 run_test 811 "orphan name stub can be cleaned up in startup"
21450
21451 test_812() {
21452         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21453                 skip "OST < 2.12.51 doesn't support this fail_loc"
21454         [ "$SHARED_KEY" = true ] &&
21455                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21456
21457         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21458         # ensure ost1 is connected
21459         stat $DIR/$tfile >/dev/null || error "can't stat"
21460         wait_osc_import_state client ost1 FULL
21461         # no locks, no reqs to let the connection idle
21462         cancel_lru_locks osc
21463
21464         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21465 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21466         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21467         wait_osc_import_state client ost1 CONNECTING
21468         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21469
21470         stat $DIR/$tfile >/dev/null || error "can't stat file"
21471 }
21472 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21473
21474 test_813() {
21475         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21476         [ -z "$file_heat_sav" ] && skip "no file heat support"
21477
21478         local readsample
21479         local writesample
21480         local readbyte
21481         local writebyte
21482         local readsample1
21483         local writesample1
21484         local readbyte1
21485         local writebyte1
21486
21487         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21488         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21489
21490         $LCTL set_param -n llite.*.file_heat=1
21491         echo "Turn on file heat"
21492         echo "Period second: $period_second, Decay percentage: $decay_pct"
21493
21494         echo "QQQQ" > $DIR/$tfile
21495         echo "QQQQ" > $DIR/$tfile
21496         echo "QQQQ" > $DIR/$tfile
21497         cat $DIR/$tfile > /dev/null
21498         cat $DIR/$tfile > /dev/null
21499         cat $DIR/$tfile > /dev/null
21500         cat $DIR/$tfile > /dev/null
21501
21502         local out=$($LFS heat_get $DIR/$tfile)
21503
21504         $LFS heat_get $DIR/$tfile
21505         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21506         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21507         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21508         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21509
21510         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21511         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21512         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21513         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21514
21515         sleep $((period_second + 3))
21516         echo "Sleep $((period_second + 3)) seconds..."
21517         # The recursion formula to calculate the heat of the file f is as
21518         # follow:
21519         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21520         # Where Hi is the heat value in the period between time points i*I and
21521         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21522         # to the weight of Ci.
21523         out=$($LFS heat_get $DIR/$tfile)
21524         $LFS heat_get $DIR/$tfile
21525         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21526         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21527         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21528         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21529
21530         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21531                 error "read sample ($readsample) is wrong"
21532         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21533                 error "write sample ($writesample) is wrong"
21534         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21535                 error "read bytes ($readbyte) is wrong"
21536         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21537                 error "write bytes ($writebyte) is wrong"
21538
21539         echo "QQQQ" > $DIR/$tfile
21540         echo "QQQQ" > $DIR/$tfile
21541         echo "QQQQ" > $DIR/$tfile
21542         cat $DIR/$tfile > /dev/null
21543         cat $DIR/$tfile > /dev/null
21544         cat $DIR/$tfile > /dev/null
21545         cat $DIR/$tfile > /dev/null
21546
21547         sleep $((period_second + 3))
21548         echo "Sleep $((period_second + 3)) seconds..."
21549
21550         out=$($LFS heat_get $DIR/$tfile)
21551         $LFS heat_get $DIR/$tfile
21552         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21553         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21554         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21555         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21556
21557         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21558                 4 * $decay_pct) / 100") -eq 1 ] ||
21559                 error "read sample ($readsample1) is wrong"
21560         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21561                 3 * $decay_pct) / 100") -eq 1 ] ||
21562                 error "write sample ($writesample1) is wrong"
21563         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21564                 20 * $decay_pct) / 100") -eq 1 ] ||
21565                 error "read bytes ($readbyte1) is wrong"
21566         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21567                 15 * $decay_pct) / 100") -eq 1 ] ||
21568                 error "write bytes ($writebyte1) is wrong"
21569
21570         echo "Turn off file heat for the file $DIR/$tfile"
21571         $LFS heat_set -o $DIR/$tfile
21572
21573         echo "QQQQ" > $DIR/$tfile
21574         echo "QQQQ" > $DIR/$tfile
21575         echo "QQQQ" > $DIR/$tfile
21576         cat $DIR/$tfile > /dev/null
21577         cat $DIR/$tfile > /dev/null
21578         cat $DIR/$tfile > /dev/null
21579         cat $DIR/$tfile > /dev/null
21580
21581         out=$($LFS heat_get $DIR/$tfile)
21582         $LFS heat_get $DIR/$tfile
21583         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21584         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21585         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21586         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21587
21588         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21589         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21590         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21591         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21592
21593         echo "Trun on file heat for the file $DIR/$tfile"
21594         $LFS heat_set -O $DIR/$tfile
21595
21596         echo "QQQQ" > $DIR/$tfile
21597         echo "QQQQ" > $DIR/$tfile
21598         echo "QQQQ" > $DIR/$tfile
21599         cat $DIR/$tfile > /dev/null
21600         cat $DIR/$tfile > /dev/null
21601         cat $DIR/$tfile > /dev/null
21602         cat $DIR/$tfile > /dev/null
21603
21604         out=$($LFS heat_get $DIR/$tfile)
21605         $LFS heat_get $DIR/$tfile
21606         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21607         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21608         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21609         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21610
21611         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21612         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21613         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21614         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21615
21616         $LFS heat_set -c $DIR/$tfile
21617         $LCTL set_param -n llite.*.file_heat=0
21618         echo "Turn off file heat support for the Lustre filesystem"
21619
21620         echo "QQQQ" > $DIR/$tfile
21621         echo "QQQQ" > $DIR/$tfile
21622         echo "QQQQ" > $DIR/$tfile
21623         cat $DIR/$tfile > /dev/null
21624         cat $DIR/$tfile > /dev/null
21625         cat $DIR/$tfile > /dev/null
21626         cat $DIR/$tfile > /dev/null
21627
21628         out=$($LFS heat_get $DIR/$tfile)
21629         $LFS heat_get $DIR/$tfile
21630         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21631         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21632         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21633         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21634
21635         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21636         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21637         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21638         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21639
21640         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21641         rm -f $DIR/$tfile
21642 }
21643 run_test 813 "File heat verfication"
21644
21645 test_814()
21646 {
21647         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21648         echo -n y >> $DIR/$tfile
21649         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21650         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21651 }
21652 run_test 814 "sparse cp works as expected (LU-12361)"
21653
21654 test_815()
21655 {
21656         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21657         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21658 }
21659 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21660
21661 test_816() {
21662         [ "$SHARED_KEY" = true ] &&
21663                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21664
21665         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21666         # ensure ost1 is connected
21667         stat $DIR/$tfile >/dev/null || error "can't stat"
21668         wait_osc_import_state client ost1 FULL
21669         # no locks, no reqs to let the connection idle
21670         cancel_lru_locks osc
21671         lru_resize_disable osc
21672         local before
21673         local now
21674         before=$($LCTL get_param -n \
21675                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21676
21677         wait_osc_import_state client ost1 IDLE
21678         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21679         now=$($LCTL get_param -n \
21680               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21681         [ $before == $now ] || error "lru_size changed $before != $now"
21682 }
21683 run_test 816 "do not reset lru_resize on idle reconnect"
21684
21685 cleanup_817() {
21686         umount $tmpdir
21687         exportfs -u localhost:$DIR/nfsexp
21688         rm -rf $DIR/nfsexp
21689 }
21690
21691 test_817() {
21692         systemctl restart nfs-server.service || skip "failed to restart nfsd"
21693
21694         mkdir -p $DIR/nfsexp
21695         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
21696                 error "failed to export nfs"
21697
21698         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
21699         stack_trap cleanup_817 EXIT
21700
21701         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
21702                 error "failed to mount nfs to $tmpdir"
21703
21704         cp /bin/true $tmpdir
21705         $DIR/nfsexp/true || error "failed to execute 'true' command"
21706 }
21707 run_test 817 "nfsd won't cache write lock for exec file"
21708
21709 #
21710 # tests that do cleanup/setup should be run at the end
21711 #
21712
21713 test_900() {
21714         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21715         local ls
21716
21717         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21718         $LCTL set_param fail_loc=0x903
21719
21720         cancel_lru_locks MGC
21721
21722         FAIL_ON_ERROR=true cleanup
21723         FAIL_ON_ERROR=true setup
21724 }
21725 run_test 900 "umount should not race with any mgc requeue thread"
21726
21727 complete $SECONDS
21728 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21729 check_and_cleanup_lustre
21730 if [ "$I_MOUNTED" != "yes" ]; then
21731         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21732 fi
21733 exit_status