Whamcloud - gitweb
LU-12639 tests: initialize variable sanity 317
[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-11594 LU-11667 LU-11729 LU-4398
57         ALWAYS_EXCEPT+=" 45       103a      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 TEMPNAME=$(mktemp $1_XXXXXX)
3086         mlink $TEMPNAME $1 2> /dev/null &&
3087                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3088         munlink $TEMPNAME
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)
13834         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13835         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13836         # some delay may occur during ChangeLog publishing and file read just
13837         # above, that could allow file write to happen finally
13838         [[ -s $tempfile ]] && echo "file should be empty"
13839
13840         $LCTL set_param fail_loc=0
13841
13842         wait $pid
13843         [[ $? -eq 0 ]] || error "create failed"
13844 }
13845 run_test 161d "create with concurrent .lustre/fid access"
13846
13847 check_path() {
13848         local expected="$1"
13849         shift
13850         local fid="$2"
13851
13852         local path
13853         path=$($LFS fid2path "$@")
13854         local rc=$?
13855
13856         if [ $rc -ne 0 ]; then
13857                 error "path looked up of '$expected' failed: rc=$rc"
13858         elif [ "$path" != "$expected" ]; then
13859                 error "path looked up '$path' instead of '$expected'"
13860         else
13861                 echo "FID '$fid' resolves to path '$path' as expected"
13862         fi
13863 }
13864
13865 test_162a() { # was test_162
13866         test_mkdir -p -c1 $DIR/$tdir/d2
13867         touch $DIR/$tdir/d2/$tfile
13868         touch $DIR/$tdir/d2/x1
13869         touch $DIR/$tdir/d2/x2
13870         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13871         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13872         # regular file
13873         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13874         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13875
13876         # softlink
13877         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13878         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13879         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13880
13881         # softlink to wrong file
13882         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13883         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13884         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13885
13886         # hardlink
13887         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13888         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13889         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13890         # fid2path dir/fsname should both work
13891         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13892         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13893
13894         # hardlink count: check that there are 2 links
13895         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13896         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13897
13898         # hardlink indexing: remove the first link
13899         rm $DIR/$tdir/d2/p/q/r/hlink
13900         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13901 }
13902 run_test 162a "path lookup sanity"
13903
13904 test_162b() {
13905         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13906         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13907
13908         mkdir $DIR/$tdir
13909         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13910                                 error "create striped dir failed"
13911
13912         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13913                                         tail -n 1 | awk '{print $2}')
13914         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13915
13916         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13917         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13918
13919         # regular file
13920         for ((i=0;i<5;i++)); do
13921                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13922                         error "get fid for f$i failed"
13923                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13924
13925                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13926                         error "get fid for d$i failed"
13927                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13928         done
13929
13930         return 0
13931 }
13932 run_test 162b "striped directory path lookup sanity"
13933
13934 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13935 test_162c() {
13936         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13937                 skip "Need MDS version at least 2.7.51"
13938
13939         local lpath=$tdir.local
13940         local rpath=$tdir.remote
13941
13942         test_mkdir $DIR/$lpath
13943         test_mkdir $DIR/$rpath
13944
13945         for ((i = 0; i <= 101; i++)); do
13946                 lpath="$lpath/$i"
13947                 mkdir $DIR/$lpath
13948                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13949                         error "get fid for local directory $DIR/$lpath failed"
13950                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13951
13952                 rpath="$rpath/$i"
13953                 test_mkdir $DIR/$rpath
13954                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13955                         error "get fid for remote directory $DIR/$rpath failed"
13956                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13957         done
13958
13959         return 0
13960 }
13961 run_test 162c "fid2path works with paths 100 or more directories deep"
13962
13963 test_169() {
13964         # do directio so as not to populate the page cache
13965         log "creating a 10 Mb file"
13966         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13967         log "starting reads"
13968         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13969         log "truncating the file"
13970         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13971         log "killing dd"
13972         kill %+ || true # reads might have finished
13973         echo "wait until dd is finished"
13974         wait
13975         log "removing the temporary file"
13976         rm -rf $DIR/$tfile || error "tmp file removal failed"
13977 }
13978 run_test 169 "parallel read and truncate should not deadlock"
13979
13980 test_170() {
13981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13982
13983         $LCTL clear     # bug 18514
13984         $LCTL debug_daemon start $TMP/${tfile}_log_good
13985         touch $DIR/$tfile
13986         $LCTL debug_daemon stop
13987         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13988                 error "sed failed to read log_good"
13989
13990         $LCTL debug_daemon start $TMP/${tfile}_log_good
13991         rm -rf $DIR/$tfile
13992         $LCTL debug_daemon stop
13993
13994         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13995                error "lctl df log_bad failed"
13996
13997         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13998         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13999
14000         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14001         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14002
14003         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14004                 error "bad_line good_line1 good_line2 are empty"
14005
14006         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14007         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14008         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14009
14010         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14011         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14012         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14013
14014         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14015                 error "bad_line_new good_line_new are empty"
14016
14017         local expected_good=$((good_line1 + good_line2*2))
14018
14019         rm -f $TMP/${tfile}*
14020         # LU-231, short malformed line may not be counted into bad lines
14021         if [ $bad_line -ne $bad_line_new ] &&
14022                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14023                 error "expected $bad_line bad lines, but got $bad_line_new"
14024                 return 1
14025         fi
14026
14027         if [ $expected_good -ne $good_line_new ]; then
14028                 error "expected $expected_good good lines, but got $good_line_new"
14029                 return 2
14030         fi
14031         true
14032 }
14033 run_test 170 "test lctl df to handle corrupted log ====================="
14034
14035 test_171() { # bug20592
14036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14037
14038         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14039         $LCTL set_param fail_loc=0x50e
14040         $LCTL set_param fail_val=3000
14041         multiop_bg_pause $DIR/$tfile O_s || true
14042         local MULTIPID=$!
14043         kill -USR1 $MULTIPID
14044         # cause log dump
14045         sleep 3
14046         wait $MULTIPID
14047         if dmesg | grep "recursive fault"; then
14048                 error "caught a recursive fault"
14049         fi
14050         $LCTL set_param fail_loc=0
14051         true
14052 }
14053 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14054
14055 # it would be good to share it with obdfilter-survey/iokit-libecho code
14056 setup_obdecho_osc () {
14057         local rc=0
14058         local ost_nid=$1
14059         local obdfilter_name=$2
14060         echo "Creating new osc for $obdfilter_name on $ost_nid"
14061         # make sure we can find loopback nid
14062         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14063
14064         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14065                            ${obdfilter_name}_osc_UUID || rc=2; }
14066         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14067                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14068         return $rc
14069 }
14070
14071 cleanup_obdecho_osc () {
14072         local obdfilter_name=$1
14073         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14074         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14075         return 0
14076 }
14077
14078 obdecho_test() {
14079         local OBD=$1
14080         local node=$2
14081         local pages=${3:-64}
14082         local rc=0
14083         local id
14084
14085         local count=10
14086         local obd_size=$(get_obd_size $node $OBD)
14087         local page_size=$(get_page_size $node)
14088         if [[ -n "$obd_size" ]]; then
14089                 local new_count=$((obd_size / (pages * page_size / 1024)))
14090                 [[ $new_count -ge $count ]] || count=$new_count
14091         fi
14092
14093         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14094         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14095                            rc=2; }
14096         if [ $rc -eq 0 ]; then
14097             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14098             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14099         fi
14100         echo "New object id is $id"
14101         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14102                            rc=4; }
14103         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14104                            "test_brw $count w v $pages $id" || rc=4; }
14105         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14106                            rc=4; }
14107         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14108                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14109         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14110                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14111         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14112         return $rc
14113 }
14114
14115 test_180a() {
14116         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14117
14118         if ! module_loaded obdecho; then
14119                 load_module obdecho/obdecho &&
14120                         stack_trap "rmmod obdecho" EXIT ||
14121                         error "unable to load obdecho on client"
14122         fi
14123
14124         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14125         local host=$($LCTL get_param -n osc.$osc.import |
14126                      awk '/current_connection:/ { print $2 }' )
14127         local target=$($LCTL get_param -n osc.$osc.import |
14128                        awk '/target:/ { print $2 }' )
14129         target=${target%_UUID}
14130
14131         if [ -n "$target" ]; then
14132                 setup_obdecho_osc $host $target &&
14133                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14134                         { error "obdecho setup failed with $?"; return; }
14135
14136                 obdecho_test ${target}_osc client ||
14137                         error "obdecho_test failed on ${target}_osc"
14138         else
14139                 $LCTL get_param osc.$osc.import
14140                 error "there is no osc.$osc.import target"
14141         fi
14142 }
14143 run_test 180a "test obdecho on osc"
14144
14145 test_180b() {
14146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14147         remote_ost_nodsh && skip "remote OST with nodsh"
14148
14149         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14150                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14151                 error "failed to load module obdecho"
14152
14153         local target=$(do_facet ost1 $LCTL dl |
14154                        awk '/obdfilter/ { print $4; exit; }')
14155
14156         if [ -n "$target" ]; then
14157                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14158         else
14159                 do_facet ost1 $LCTL dl
14160                 error "there is no obdfilter target on ost1"
14161         fi
14162 }
14163 run_test 180b "test obdecho directly on obdfilter"
14164
14165 test_180c() { # LU-2598
14166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14167         remote_ost_nodsh && skip "remote OST with nodsh"
14168         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14169                 skip "Need MDS version at least 2.4.0"
14170
14171         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14172                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14173                 error "failed to load module obdecho"
14174
14175         local target=$(do_facet ost1 $LCTL dl |
14176                        awk '/obdfilter/ { print $4; exit; }')
14177
14178         if [ -n "$target" ]; then
14179                 local pages=16384 # 64MB bulk I/O RPC size
14180
14181                 obdecho_test "$target" ost1 "$pages" ||
14182                         error "obdecho_test with pages=$pages failed with $?"
14183         else
14184                 do_facet ost1 $LCTL dl
14185                 error "there is no obdfilter target on ost1"
14186         fi
14187 }
14188 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14189
14190 test_181() { # bug 22177
14191         test_mkdir $DIR/$tdir
14192         # create enough files to index the directory
14193         createmany -o $DIR/$tdir/foobar 4000
14194         # print attributes for debug purpose
14195         lsattr -d .
14196         # open dir
14197         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14198         MULTIPID=$!
14199         # remove the files & current working dir
14200         unlinkmany $DIR/$tdir/foobar 4000
14201         rmdir $DIR/$tdir
14202         kill -USR1 $MULTIPID
14203         wait $MULTIPID
14204         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14205         return 0
14206 }
14207 run_test 181 "Test open-unlinked dir ========================"
14208
14209 test_182() {
14210         local fcount=1000
14211         local tcount=10
14212
14213         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14214
14215         $LCTL set_param mdc.*.rpc_stats=clear
14216
14217         for (( i = 0; i < $tcount; i++ )) ; do
14218                 mkdir $DIR/$tdir/$i
14219         done
14220
14221         for (( i = 0; i < $tcount; i++ )) ; do
14222                 createmany -o $DIR/$tdir/$i/f- $fcount &
14223         done
14224         wait
14225
14226         for (( i = 0; i < $tcount; i++ )) ; do
14227                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14228         done
14229         wait
14230
14231         $LCTL get_param mdc.*.rpc_stats
14232
14233         rm -rf $DIR/$tdir
14234 }
14235 run_test 182 "Test parallel modify metadata operations ================"
14236
14237 test_183() { # LU-2275
14238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14239         remote_mds_nodsh && skip "remote MDS with nodsh"
14240         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14241                 skip "Need MDS version at least 2.3.56"
14242
14243         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14244         echo aaa > $DIR/$tdir/$tfile
14245
14246 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14247         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14248
14249         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14250         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14251
14252         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14253
14254         # Flush negative dentry cache
14255         touch $DIR/$tdir/$tfile
14256
14257         # We are not checking for any leaked references here, they'll
14258         # become evident next time we do cleanup with module unload.
14259         rm -rf $DIR/$tdir
14260 }
14261 run_test 183 "No crash or request leak in case of strange dispositions ========"
14262
14263 # test suite 184 is for LU-2016, LU-2017
14264 test_184a() {
14265         check_swap_layouts_support
14266
14267         dir0=$DIR/$tdir/$testnum
14268         test_mkdir -p -c1 $dir0
14269         ref1=/etc/passwd
14270         ref2=/etc/group
14271         file1=$dir0/f1
14272         file2=$dir0/f2
14273         $LFS setstripe -c1 $file1
14274         cp $ref1 $file1
14275         $LFS setstripe -c2 $file2
14276         cp $ref2 $file2
14277         gen1=$($LFS getstripe -g $file1)
14278         gen2=$($LFS getstripe -g $file2)
14279
14280         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14281         gen=$($LFS getstripe -g $file1)
14282         [[ $gen1 != $gen ]] ||
14283                 "Layout generation on $file1 does not change"
14284         gen=$($LFS getstripe -g $file2)
14285         [[ $gen2 != $gen ]] ||
14286                 "Layout generation on $file2 does not change"
14287
14288         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14289         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14290
14291         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14292 }
14293 run_test 184a "Basic layout swap"
14294
14295 test_184b() {
14296         check_swap_layouts_support
14297
14298         dir0=$DIR/$tdir/$testnum
14299         mkdir -p $dir0 || error "creating dir $dir0"
14300         file1=$dir0/f1
14301         file2=$dir0/f2
14302         file3=$dir0/f3
14303         dir1=$dir0/d1
14304         dir2=$dir0/d2
14305         mkdir $dir1 $dir2
14306         $LFS setstripe -c1 $file1
14307         $LFS setstripe -c2 $file2
14308         $LFS setstripe -c1 $file3
14309         chown $RUNAS_ID $file3
14310         gen1=$($LFS getstripe -g $file1)
14311         gen2=$($LFS getstripe -g $file2)
14312
14313         $LFS swap_layouts $dir1 $dir2 &&
14314                 error "swap of directories layouts should fail"
14315         $LFS swap_layouts $dir1 $file1 &&
14316                 error "swap of directory and file layouts should fail"
14317         $RUNAS $LFS swap_layouts $file1 $file2 &&
14318                 error "swap of file we cannot write should fail"
14319         $LFS swap_layouts $file1 $file3 &&
14320                 error "swap of file with different owner should fail"
14321         /bin/true # to clear error code
14322 }
14323 run_test 184b "Forbidden layout swap (will generate errors)"
14324
14325 test_184c() {
14326         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14327         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14328         check_swap_layouts_support
14329
14330         local dir0=$DIR/$tdir/$testnum
14331         mkdir -p $dir0 || error "creating dir $dir0"
14332
14333         local ref1=$dir0/ref1
14334         local ref2=$dir0/ref2
14335         local file1=$dir0/file1
14336         local file2=$dir0/file2
14337         # create a file large enough for the concurrent test
14338         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14339         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14340         echo "ref file size: ref1($(stat -c %s $ref1))," \
14341              "ref2($(stat -c %s $ref2))"
14342
14343         cp $ref2 $file2
14344         dd if=$ref1 of=$file1 bs=16k &
14345         local DD_PID=$!
14346
14347         # Make sure dd starts to copy file
14348         while [ ! -f $file1 ]; do sleep 0.1; done
14349
14350         $LFS swap_layouts $file1 $file2
14351         local rc=$?
14352         wait $DD_PID
14353         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14354         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14355
14356         # how many bytes copied before swapping layout
14357         local copied=$(stat -c %s $file2)
14358         local remaining=$(stat -c %s $ref1)
14359         remaining=$((remaining - copied))
14360         echo "Copied $copied bytes before swapping layout..."
14361
14362         cmp -n $copied $file1 $ref2 | grep differ &&
14363                 error "Content mismatch [0, $copied) of ref2 and file1"
14364         cmp -n $copied $file2 $ref1 ||
14365                 error "Content mismatch [0, $copied) of ref1 and file2"
14366         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14367                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14368
14369         # clean up
14370         rm -f $ref1 $ref2 $file1 $file2
14371 }
14372 run_test 184c "Concurrent write and layout swap"
14373
14374 test_184d() {
14375         check_swap_layouts_support
14376         [ -z "$(which getfattr 2>/dev/null)" ] &&
14377                 skip_env "no getfattr command"
14378
14379         local file1=$DIR/$tdir/$tfile-1
14380         local file2=$DIR/$tdir/$tfile-2
14381         local file3=$DIR/$tdir/$tfile-3
14382         local lovea1
14383         local lovea2
14384
14385         mkdir -p $DIR/$tdir
14386         touch $file1 || error "create $file1 failed"
14387         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14388                 error "create $file2 failed"
14389         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14390                 error "create $file3 failed"
14391         lovea1=$(get_layout_param $file1)
14392
14393         $LFS swap_layouts $file2 $file3 ||
14394                 error "swap $file2 $file3 layouts failed"
14395         $LFS swap_layouts $file1 $file2 ||
14396                 error "swap $file1 $file2 layouts failed"
14397
14398         lovea2=$(get_layout_param $file2)
14399         echo "$lovea1"
14400         echo "$lovea2"
14401         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14402
14403         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14404         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14405 }
14406 run_test 184d "allow stripeless layouts swap"
14407
14408 test_184e() {
14409         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14410                 skip "Need MDS version at least 2.6.94"
14411         check_swap_layouts_support
14412         [ -z "$(which getfattr 2>/dev/null)" ] &&
14413                 skip_env "no getfattr command"
14414
14415         local file1=$DIR/$tdir/$tfile-1
14416         local file2=$DIR/$tdir/$tfile-2
14417         local file3=$DIR/$tdir/$tfile-3
14418         local lovea
14419
14420         mkdir -p $DIR/$tdir
14421         touch $file1 || error "create $file1 failed"
14422         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14423                 error "create $file2 failed"
14424         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14425                 error "create $file3 failed"
14426
14427         $LFS swap_layouts $file1 $file2 ||
14428                 error "swap $file1 $file2 layouts failed"
14429
14430         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14431         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14432
14433         echo 123 > $file1 || error "Should be able to write into $file1"
14434
14435         $LFS swap_layouts $file1 $file3 ||
14436                 error "swap $file1 $file3 layouts failed"
14437
14438         echo 123 > $file1 || error "Should be able to write into $file1"
14439
14440         rm -rf $file1 $file2 $file3
14441 }
14442 run_test 184e "Recreate layout after stripeless layout swaps"
14443
14444 test_184f() {
14445         # Create a file with name longer than sizeof(struct stat) ==
14446         # 144 to see if we can get chars from the file name to appear
14447         # in the returned striping. Note that 'f' == 0x66.
14448         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14449
14450         mkdir -p $DIR/$tdir
14451         mcreate $DIR/$tdir/$file
14452         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14453                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14454         fi
14455 }
14456 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14457
14458 test_185() { # LU-2441
14459         # LU-3553 - no volatile file support in old servers
14460         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14461                 skip "Need MDS version at least 2.3.60"
14462
14463         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14464         touch $DIR/$tdir/spoo
14465         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14466         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14467                 error "cannot create/write a volatile file"
14468         [ "$FILESET" == "" ] &&
14469         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14470                 error "FID is still valid after close"
14471
14472         multiop_bg_pause $DIR/$tdir vVw4096_c
14473         local multi_pid=$!
14474
14475         local OLD_IFS=$IFS
14476         IFS=":"
14477         local fidv=($fid)
14478         IFS=$OLD_IFS
14479         # assume that the next FID for this client is sequential, since stdout
14480         # is unfortunately eaten by multiop_bg_pause
14481         local n=$((${fidv[1]} + 1))
14482         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14483         if [ "$FILESET" == "" ]; then
14484                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14485                         error "FID is missing before close"
14486         fi
14487         kill -USR1 $multi_pid
14488         # 1 second delay, so if mtime change we will see it
14489         sleep 1
14490         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14491         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14492 }
14493 run_test 185 "Volatile file support"
14494
14495 function create_check_volatile() {
14496         local idx=$1
14497         local tgt
14498
14499         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
14500         local PID=$!
14501         sleep 1
14502         local FID=$(cat /tmp/${tfile}.fid)
14503         [ "$FID" == "" ] && error "can't get FID for volatile"
14504         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
14505         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
14506         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
14507         kill -USR1 $PID
14508         wait
14509         sleep 1
14510         cancel_lru_locks mdc # flush opencache
14511         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
14512         return 0
14513 }
14514
14515 test_185a(){
14516         # LU-12516 - volatile creation via .lustre
14517         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
14518                 skip "Need MDS version at least 2.3.55"
14519
14520         create_check_volatile 0
14521         [ $MDSCOUNT -lt 2 ] && return 0
14522
14523         # DNE case
14524         create_check_volatile 1
14525
14526         return 0
14527 }
14528 run_test 185a "Volatile file creation in .lustre/fid/"
14529
14530 test_187a() {
14531         remote_mds_nodsh && skip "remote MDS with nodsh"
14532         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14533                 skip "Need MDS version at least 2.3.0"
14534
14535         local dir0=$DIR/$tdir/$testnum
14536         mkdir -p $dir0 || error "creating dir $dir0"
14537
14538         local file=$dir0/file1
14539         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14540         local dv1=$($LFS data_version $file)
14541         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14542         local dv2=$($LFS data_version $file)
14543         [[ $dv1 != $dv2 ]] ||
14544                 error "data version did not change on write $dv1 == $dv2"
14545
14546         # clean up
14547         rm -f $file1
14548 }
14549 run_test 187a "Test data version change"
14550
14551 test_187b() {
14552         remote_mds_nodsh && skip "remote MDS with nodsh"
14553         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14554                 skip "Need MDS version at least 2.3.0"
14555
14556         local dir0=$DIR/$tdir/$testnum
14557         mkdir -p $dir0 || error "creating dir $dir0"
14558
14559         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14560         [[ ${DV[0]} != ${DV[1]} ]] ||
14561                 error "data version did not change on write"\
14562                       " ${DV[0]} == ${DV[1]}"
14563
14564         # clean up
14565         rm -f $file1
14566 }
14567 run_test 187b "Test data version change on volatile file"
14568
14569 test_200() {
14570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14571         remote_mgs_nodsh && skip "remote MGS with nodsh"
14572         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14573
14574         local POOL=${POOL:-cea1}
14575         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14576         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14577         # Pool OST targets
14578         local first_ost=0
14579         local last_ost=$(($OSTCOUNT - 1))
14580         local ost_step=2
14581         local ost_list=$(seq $first_ost $ost_step $last_ost)
14582         local ost_range="$first_ost $last_ost $ost_step"
14583         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14584         local file_dir=$POOL_ROOT/file_tst
14585         local subdir=$test_path/subdir
14586         local rc=0
14587
14588         if ! combined_mgs_mds ; then
14589                 mount_mgs_client
14590         fi
14591
14592         while : ; do
14593                 # former test_200a test_200b
14594                 pool_add $POOL                          || { rc=$? ; break; }
14595                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14596                 # former test_200c test_200d
14597                 mkdir -p $test_path
14598                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14599                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14600                 mkdir -p $subdir
14601                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14602                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14603                                                         || { rc=$? ; break; }
14604                 # former test_200e test_200f
14605                 local files=$((OSTCOUNT*3))
14606                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14607                                                         || { rc=$? ; break; }
14608                 pool_create_files $POOL $file_dir $files "$ost_list" \
14609                                                         || { rc=$? ; break; }
14610                 # former test_200g test_200h
14611                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14612                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14613
14614                 # former test_201a test_201b test_201c
14615                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14616
14617                 local f=$test_path/$tfile
14618                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14619                 pool_remove $POOL $f                    || { rc=$? ; break; }
14620                 break
14621         done
14622
14623         destroy_test_pools
14624
14625         if ! combined_mgs_mds ; then
14626                 umount_mgs_client
14627         fi
14628         return $rc
14629 }
14630 run_test 200 "OST pools"
14631
14632 # usage: default_attr <count | size | offset>
14633 default_attr() {
14634         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14635 }
14636
14637 # usage: check_default_stripe_attr
14638 check_default_stripe_attr() {
14639         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14640         case $1 in
14641         --stripe-count|-c)
14642                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14643         --stripe-size|-S)
14644                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14645         --stripe-index|-i)
14646                 EXPECTED=-1;;
14647         *)
14648                 error "unknown getstripe attr '$1'"
14649         esac
14650
14651         [ $ACTUAL == $EXPECTED ] ||
14652                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14653 }
14654
14655 test_204a() {
14656         test_mkdir $DIR/$tdir
14657         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14658
14659         check_default_stripe_attr --stripe-count
14660         check_default_stripe_attr --stripe-size
14661         check_default_stripe_attr --stripe-index
14662 }
14663 run_test 204a "Print default stripe attributes"
14664
14665 test_204b() {
14666         test_mkdir $DIR/$tdir
14667         $LFS setstripe --stripe-count 1 $DIR/$tdir
14668
14669         check_default_stripe_attr --stripe-size
14670         check_default_stripe_attr --stripe-index
14671 }
14672 run_test 204b "Print default stripe size and offset"
14673
14674 test_204c() {
14675         test_mkdir $DIR/$tdir
14676         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14677
14678         check_default_stripe_attr --stripe-count
14679         check_default_stripe_attr --stripe-index
14680 }
14681 run_test 204c "Print default stripe count and offset"
14682
14683 test_204d() {
14684         test_mkdir $DIR/$tdir
14685         $LFS setstripe --stripe-index 0 $DIR/$tdir
14686
14687         check_default_stripe_attr --stripe-count
14688         check_default_stripe_attr --stripe-size
14689 }
14690 run_test 204d "Print default stripe count and size"
14691
14692 test_204e() {
14693         test_mkdir $DIR/$tdir
14694         $LFS setstripe -d $DIR/$tdir
14695
14696         check_default_stripe_attr --stripe-count --raw
14697         check_default_stripe_attr --stripe-size --raw
14698         check_default_stripe_attr --stripe-index --raw
14699 }
14700 run_test 204e "Print raw stripe attributes"
14701
14702 test_204f() {
14703         test_mkdir $DIR/$tdir
14704         $LFS setstripe --stripe-count 1 $DIR/$tdir
14705
14706         check_default_stripe_attr --stripe-size --raw
14707         check_default_stripe_attr --stripe-index --raw
14708 }
14709 run_test 204f "Print raw stripe size and offset"
14710
14711 test_204g() {
14712         test_mkdir $DIR/$tdir
14713         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14714
14715         check_default_stripe_attr --stripe-count --raw
14716         check_default_stripe_attr --stripe-index --raw
14717 }
14718 run_test 204g "Print raw stripe count and offset"
14719
14720 test_204h() {
14721         test_mkdir $DIR/$tdir
14722         $LFS setstripe --stripe-index 0 $DIR/$tdir
14723
14724         check_default_stripe_attr --stripe-count --raw
14725         check_default_stripe_attr --stripe-size --raw
14726 }
14727 run_test 204h "Print raw stripe count and size"
14728
14729 # Figure out which job scheduler is being used, if any,
14730 # or use a fake one
14731 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14732         JOBENV=SLURM_JOB_ID
14733 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14734         JOBENV=LSB_JOBID
14735 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14736         JOBENV=PBS_JOBID
14737 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14738         JOBENV=LOADL_STEP_ID
14739 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14740         JOBENV=JOB_ID
14741 else
14742         $LCTL list_param jobid_name > /dev/null 2>&1
14743         if [ $? -eq 0 ]; then
14744                 JOBENV=nodelocal
14745         else
14746                 JOBENV=FAKE_JOBID
14747         fi
14748 fi
14749 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14750
14751 verify_jobstats() {
14752         local cmd=($1)
14753         shift
14754         local facets="$@"
14755
14756 # we don't really need to clear the stats for this test to work, since each
14757 # command has a unique jobid, but it makes debugging easier if needed.
14758 #       for facet in $facets; do
14759 #               local dev=$(convert_facet2label $facet)
14760 #               # clear old jobstats
14761 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14762 #       done
14763
14764         # use a new JobID for each test, or we might see an old one
14765         [ "$JOBENV" = "FAKE_JOBID" ] &&
14766                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14767
14768         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14769
14770         [ "$JOBENV" = "nodelocal" ] && {
14771                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14772                 $LCTL set_param jobid_name=$FAKE_JOBID
14773                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14774         }
14775
14776         log "Test: ${cmd[*]}"
14777         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14778
14779         if [ $JOBENV = "FAKE_JOBID" ]; then
14780                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14781         else
14782                 ${cmd[*]}
14783         fi
14784
14785         # all files are created on OST0000
14786         for facet in $facets; do
14787                 local stats="*.$(convert_facet2label $facet).job_stats"
14788
14789                 # strip out libtool wrappers for in-tree executables
14790                 if [ $(do_facet $facet lctl get_param $stats |
14791                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14792                         do_facet $facet lctl get_param $stats
14793                         error "No jobstats for $JOBVAL found on $facet::$stats"
14794                 fi
14795         done
14796 }
14797
14798 jobstats_set() {
14799         local new_jobenv=$1
14800
14801         set_persistent_param_and_check client "jobid_var" \
14802                 "$FSNAME.sys.jobid_var" $new_jobenv
14803 }
14804
14805 test_205() { # Job stats
14806         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14807         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14808                 skip "Need MDS version with at least 2.7.1"
14809         remote_mgs_nodsh && skip "remote MGS with nodsh"
14810         remote_mds_nodsh && skip "remote MDS with nodsh"
14811         remote_ost_nodsh && skip "remote OST with nodsh"
14812         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14813                 skip "Server doesn't support jobstats"
14814         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14815
14816         local old_jobenv=$($LCTL get_param -n jobid_var)
14817         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14818
14819         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14820                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14821         else
14822                 stack_trap "do_facet mgs $PERM_CMD \
14823                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14824         fi
14825         changelog_register
14826
14827         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14828                                 mdt.*.job_cleanup_interval | head -n 1)
14829         local new_interval=5
14830         do_facet $SINGLEMDS \
14831                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14832         stack_trap "do_facet $SINGLEMDS \
14833                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14834         local start=$SECONDS
14835
14836         local cmd
14837         # mkdir
14838         cmd="mkdir $DIR/$tdir"
14839         verify_jobstats "$cmd" "$SINGLEMDS"
14840         # rmdir
14841         cmd="rmdir $DIR/$tdir"
14842         verify_jobstats "$cmd" "$SINGLEMDS"
14843         # mkdir on secondary MDT
14844         if [ $MDSCOUNT -gt 1 ]; then
14845                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14846                 verify_jobstats "$cmd" "mds2"
14847         fi
14848         # mknod
14849         cmd="mknod $DIR/$tfile c 1 3"
14850         verify_jobstats "$cmd" "$SINGLEMDS"
14851         # unlink
14852         cmd="rm -f $DIR/$tfile"
14853         verify_jobstats "$cmd" "$SINGLEMDS"
14854         # create all files on OST0000 so verify_jobstats can find OST stats
14855         # open & close
14856         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14857         verify_jobstats "$cmd" "$SINGLEMDS"
14858         # setattr
14859         cmd="touch $DIR/$tfile"
14860         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14861         # write
14862         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14863         verify_jobstats "$cmd" "ost1"
14864         # read
14865         cancel_lru_locks osc
14866         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14867         verify_jobstats "$cmd" "ost1"
14868         # truncate
14869         cmd="$TRUNCATE $DIR/$tfile 0"
14870         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14871         # rename
14872         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14873         verify_jobstats "$cmd" "$SINGLEMDS"
14874         # jobstats expiry - sleep until old stats should be expired
14875         local left=$((new_interval + 5 - (SECONDS - start)))
14876         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14877                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14878                         "0" $left
14879         cmd="mkdir $DIR/$tdir.expire"
14880         verify_jobstats "$cmd" "$SINGLEMDS"
14881         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14882             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14883
14884         # Ensure that jobid are present in changelog (if supported by MDS)
14885         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14886                 changelog_dump | tail -10
14887                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14888                 [ $jobids -eq 9 ] ||
14889                         error "Wrong changelog jobid count $jobids != 9"
14890
14891                 # LU-5862
14892                 JOBENV="disable"
14893                 jobstats_set $JOBENV
14894                 touch $DIR/$tfile
14895                 changelog_dump | grep $tfile
14896                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14897                 [ $jobids -eq 0 ] ||
14898                         error "Unexpected jobids when jobid_var=$JOBENV"
14899         fi
14900
14901         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14902         JOBENV="JOBCOMPLEX"
14903         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14904
14905         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14906 }
14907 run_test 205 "Verify job stats"
14908
14909 # LU-1480, LU-1773 and LU-1657
14910 test_206() {
14911         mkdir -p $DIR/$tdir
14912         $LFS setstripe -c -1 $DIR/$tdir
14913 #define OBD_FAIL_LOV_INIT 0x1403
14914         $LCTL set_param fail_loc=0xa0001403
14915         $LCTL set_param fail_val=1
14916         touch $DIR/$tdir/$tfile || true
14917 }
14918 run_test 206 "fail lov_init_raid0() doesn't lbug"
14919
14920 test_207a() {
14921         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14922         local fsz=`stat -c %s $DIR/$tfile`
14923         cancel_lru_locks mdc
14924
14925         # do not return layout in getattr intent
14926 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14927         $LCTL set_param fail_loc=0x170
14928         local sz=`stat -c %s $DIR/$tfile`
14929
14930         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14931
14932         rm -rf $DIR/$tfile
14933 }
14934 run_test 207a "can refresh layout at glimpse"
14935
14936 test_207b() {
14937         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14938         local cksum=`md5sum $DIR/$tfile`
14939         local fsz=`stat -c %s $DIR/$tfile`
14940         cancel_lru_locks mdc
14941         cancel_lru_locks osc
14942
14943         # do not return layout in getattr intent
14944 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14945         $LCTL set_param fail_loc=0x171
14946
14947         # it will refresh layout after the file is opened but before read issues
14948         echo checksum is "$cksum"
14949         echo "$cksum" |md5sum -c --quiet || error "file differs"
14950
14951         rm -rf $DIR/$tfile
14952 }
14953 run_test 207b "can refresh layout at open"
14954
14955 test_208() {
14956         # FIXME: in this test suite, only RD lease is used. This is okay
14957         # for now as only exclusive open is supported. After generic lease
14958         # is done, this test suite should be revised. - Jinshan
14959
14960         remote_mds_nodsh && skip "remote MDS with nodsh"
14961         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14962                 skip "Need MDS version at least 2.4.52"
14963
14964         echo "==== test 1: verify get lease work"
14965         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14966
14967         echo "==== test 2: verify lease can be broken by upcoming open"
14968         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14969         local PID=$!
14970         sleep 1
14971
14972         $MULTIOP $DIR/$tfile oO_RDONLY:c
14973         kill -USR1 $PID && wait $PID || error "break lease error"
14974
14975         echo "==== test 3: verify lease can't be granted if an open already exists"
14976         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14977         local PID=$!
14978         sleep 1
14979
14980         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14981         kill -USR1 $PID && wait $PID || error "open file error"
14982
14983         echo "==== test 4: lease can sustain over recovery"
14984         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14985         PID=$!
14986         sleep 1
14987
14988         fail mds1
14989
14990         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14991
14992         echo "==== test 5: lease broken can't be regained by replay"
14993         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14994         PID=$!
14995         sleep 1
14996
14997         # open file to break lease and then recovery
14998         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14999         fail mds1
15000
15001         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15002
15003         rm -f $DIR/$tfile
15004 }
15005 run_test 208 "Exclusive open"
15006
15007 test_209() {
15008         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15009                 skip_env "must have disp_stripe"
15010
15011         touch $DIR/$tfile
15012         sync; sleep 5; sync;
15013
15014         echo 3 > /proc/sys/vm/drop_caches
15015         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15016
15017         # open/close 500 times
15018         for i in $(seq 500); do
15019                 cat $DIR/$tfile
15020         done
15021
15022         echo 3 > /proc/sys/vm/drop_caches
15023         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15024
15025         echo "before: $req_before, after: $req_after"
15026         [ $((req_after - req_before)) -ge 300 ] &&
15027                 error "open/close requests are not freed"
15028         return 0
15029 }
15030 run_test 209 "read-only open/close requests should be freed promptly"
15031
15032 test_212() {
15033         size=`date +%s`
15034         size=$((size % 8192 + 1))
15035         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15036         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15037         rm -f $DIR/f212 $DIR/f212.xyz
15038 }
15039 run_test 212 "Sendfile test ============================================"
15040
15041 test_213() {
15042         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15043         cancel_lru_locks osc
15044         lctl set_param fail_loc=0x8000040f
15045         # generate a read lock
15046         cat $DIR/$tfile > /dev/null
15047         # write to the file, it will try to cancel the above read lock.
15048         cat /etc/hosts >> $DIR/$tfile
15049 }
15050 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15051
15052 test_214() { # for bug 20133
15053         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15054         for (( i=0; i < 340; i++ )) ; do
15055                 touch $DIR/$tdir/d214c/a$i
15056         done
15057
15058         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15059         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15060         ls $DIR/d214c || error "ls $DIR/d214c failed"
15061         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15062         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15063 }
15064 run_test 214 "hash-indexed directory test - bug 20133"
15065
15066 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15067 create_lnet_proc_files() {
15068         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15069 }
15070
15071 # counterpart of create_lnet_proc_files
15072 remove_lnet_proc_files() {
15073         rm -f $TMP/lnet_$1.sys
15074 }
15075
15076 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15077 # 3rd arg as regexp for body
15078 check_lnet_proc_stats() {
15079         local l=$(cat "$TMP/lnet_$1" |wc -l)
15080         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15081
15082         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15083 }
15084
15085 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15086 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15087 # optional and can be regexp for 2nd line (lnet.routes case)
15088 check_lnet_proc_entry() {
15089         local blp=2          # blp stands for 'position of 1st line of body'
15090         [ -z "$5" ] || blp=3 # lnet.routes case
15091
15092         local l=$(cat "$TMP/lnet_$1" |wc -l)
15093         # subtracting one from $blp because the body can be empty
15094         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15095
15096         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15097                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15098
15099         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15100                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15101
15102         # bail out if any unexpected line happened
15103         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15104         [ "$?" != 0 ] || error "$2 misformatted"
15105 }
15106
15107 test_215() { # for bugs 18102, 21079, 21517
15108         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15109
15110         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15111         local P='[1-9][0-9]*'           # positive numeric
15112         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15113         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15114         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15115         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15116
15117         local L1 # regexp for 1st line
15118         local L2 # regexp for 2nd line (optional)
15119         local BR # regexp for the rest (body)
15120
15121         # lnet.stats should look as 11 space-separated non-negative numerics
15122         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15123         create_lnet_proc_files "stats"
15124         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15125         remove_lnet_proc_files "stats"
15126
15127         # lnet.routes should look like this:
15128         # Routing disabled/enabled
15129         # net hops priority state router
15130         # where net is a string like tcp0, hops > 0, priority >= 0,
15131         # state is up/down,
15132         # router is a string like 192.168.1.1@tcp2
15133         L1="^Routing (disabled|enabled)$"
15134         L2="^net +hops +priority +state +router$"
15135         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15136         create_lnet_proc_files "routes"
15137         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15138         remove_lnet_proc_files "routes"
15139
15140         # lnet.routers should look like this:
15141         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15142         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15143         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15144         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15145         L1="^ref +rtr_ref +alive +router$"
15146         BR="^$P +$P +(up|down) +$NID$"
15147         create_lnet_proc_files "routers"
15148         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15149         remove_lnet_proc_files "routers"
15150
15151         # lnet.peers should look like this:
15152         # nid refs state last max rtr min tx min queue
15153         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15154         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15155         # numeric (0 or >0 or <0), queue >= 0.
15156         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15157         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15158         create_lnet_proc_files "peers"
15159         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15160         remove_lnet_proc_files "peers"
15161
15162         # lnet.buffers  should look like this:
15163         # pages count credits min
15164         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15165         L1="^pages +count +credits +min$"
15166         BR="^ +$N +$N +$I +$I$"
15167         create_lnet_proc_files "buffers"
15168         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15169         remove_lnet_proc_files "buffers"
15170
15171         # lnet.nis should look like this:
15172         # nid status alive refs peer rtr max tx min
15173         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15174         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15175         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15176         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15177         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15178         create_lnet_proc_files "nis"
15179         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15180         remove_lnet_proc_files "nis"
15181
15182         # can we successfully write to lnet.stats?
15183         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15184 }
15185 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15186
15187 test_216() { # bug 20317
15188         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15189         remote_ost_nodsh && skip "remote OST with nodsh"
15190
15191         local node
15192         local facets=$(get_facets OST)
15193         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15194
15195         save_lustre_params client "osc.*.contention_seconds" > $p
15196         save_lustre_params $facets \
15197                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15198         save_lustre_params $facets \
15199                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15200         save_lustre_params $facets \
15201                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15202         clear_stats osc.*.osc_stats
15203
15204         # agressive lockless i/o settings
15205         do_nodes $(comma_list $(osts_nodes)) \
15206                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15207                         ldlm.namespaces.filter-*.contended_locks=0 \
15208                         ldlm.namespaces.filter-*.contention_seconds=60"
15209         lctl set_param -n osc.*.contention_seconds=60
15210
15211         $DIRECTIO write $DIR/$tfile 0 10 4096
15212         $CHECKSTAT -s 40960 $DIR/$tfile
15213
15214         # disable lockless i/o
15215         do_nodes $(comma_list $(osts_nodes)) \
15216                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15217                         ldlm.namespaces.filter-*.contended_locks=32 \
15218                         ldlm.namespaces.filter-*.contention_seconds=0"
15219         lctl set_param -n osc.*.contention_seconds=0
15220         clear_stats osc.*.osc_stats
15221
15222         dd if=/dev/zero of=$DIR/$tfile count=0
15223         $CHECKSTAT -s 0 $DIR/$tfile
15224
15225         restore_lustre_params <$p
15226         rm -f $p
15227         rm $DIR/$tfile
15228 }
15229 run_test 216 "check lockless direct write updates file size and kms correctly"
15230
15231 test_217() { # bug 22430
15232         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15233
15234         local node
15235         local nid
15236
15237         for node in $(nodes_list); do
15238                 nid=$(host_nids_address $node $NETTYPE)
15239                 if [[ $nid = *-* ]] ; then
15240                         echo "lctl ping $(h2nettype $nid)"
15241                         lctl ping $(h2nettype $nid)
15242                 else
15243                         echo "skipping $node (no hyphen detected)"
15244                 fi
15245         done
15246 }
15247 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15248
15249 test_218() {
15250        # do directio so as not to populate the page cache
15251        log "creating a 10 Mb file"
15252        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15253        log "starting reads"
15254        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15255        log "truncating the file"
15256        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15257        log "killing dd"
15258        kill %+ || true # reads might have finished
15259        echo "wait until dd is finished"
15260        wait
15261        log "removing the temporary file"
15262        rm -rf $DIR/$tfile || error "tmp file removal failed"
15263 }
15264 run_test 218 "parallel read and truncate should not deadlock"
15265
15266 test_219() {
15267         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15268
15269         # write one partial page
15270         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15271         # set no grant so vvp_io_commit_write will do sync write
15272         $LCTL set_param fail_loc=0x411
15273         # write a full page at the end of file
15274         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15275
15276         $LCTL set_param fail_loc=0
15277         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15278         $LCTL set_param fail_loc=0x411
15279         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15280
15281         # LU-4201
15282         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15283         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15284 }
15285 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15286
15287 test_220() { #LU-325
15288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15289         remote_ost_nodsh && skip "remote OST with nodsh"
15290         remote_mds_nodsh && skip "remote MDS with nodsh"
15291         remote_mgs_nodsh && skip "remote MGS with nodsh"
15292
15293         local OSTIDX=0
15294
15295         # create on MDT0000 so the last_id and next_id are correct
15296         mkdir $DIR/$tdir
15297         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15298         OST=${OST%_UUID}
15299
15300         # on the mdt's osc
15301         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15302         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15303                         osp.$mdtosc_proc1.prealloc_last_id)
15304         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15305                         osp.$mdtosc_proc1.prealloc_next_id)
15306
15307         $LFS df -i
15308
15309         if ! combined_mgs_mds ; then
15310                 mount_mgs_client
15311         fi
15312
15313         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15314         #define OBD_FAIL_OST_ENOINO              0x229
15315         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15316         create_pool $FSNAME.$TESTNAME || return 1
15317         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15318
15319         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15320
15321         MDSOBJS=$((last_id - next_id))
15322         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15323
15324         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15325         echo "OST still has $count kbytes free"
15326
15327         echo "create $MDSOBJS files @next_id..."
15328         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15329
15330         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15331                         osp.$mdtosc_proc1.prealloc_last_id)
15332         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15333                         osp.$mdtosc_proc1.prealloc_next_id)
15334
15335         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15336         $LFS df -i
15337
15338         echo "cleanup..."
15339
15340         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15341         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15342
15343         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15344                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15345         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15346                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15347         echo "unlink $MDSOBJS files @$next_id..."
15348         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15349
15350         if ! combined_mgs_mds ; then
15351                 umount_mgs_client
15352         fi
15353 }
15354 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15355
15356 test_221() {
15357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15358
15359         dd if=`which date` of=$MOUNT/date oflag=sync
15360         chmod +x $MOUNT/date
15361
15362         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15363         $LCTL set_param fail_loc=0x80001401
15364
15365         $MOUNT/date > /dev/null
15366         rm -f $MOUNT/date
15367 }
15368 run_test 221 "make sure fault and truncate race to not cause OOM"
15369
15370 test_222a () {
15371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15372
15373         rm -rf $DIR/$tdir
15374         test_mkdir $DIR/$tdir
15375         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15376         createmany -o $DIR/$tdir/$tfile 10
15377         cancel_lru_locks mdc
15378         cancel_lru_locks osc
15379         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15380         $LCTL set_param fail_loc=0x31a
15381         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15382         $LCTL set_param fail_loc=0
15383         rm -r $DIR/$tdir
15384 }
15385 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15386
15387 test_222b () {
15388         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15389
15390         rm -rf $DIR/$tdir
15391         test_mkdir $DIR/$tdir
15392         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15393         createmany -o $DIR/$tdir/$tfile 10
15394         cancel_lru_locks mdc
15395         cancel_lru_locks osc
15396         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15397         $LCTL set_param fail_loc=0x31a
15398         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15399         $LCTL set_param fail_loc=0
15400 }
15401 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15402
15403 test_223 () {
15404         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15405
15406         rm -rf $DIR/$tdir
15407         test_mkdir $DIR/$tdir
15408         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15409         createmany -o $DIR/$tdir/$tfile 10
15410         cancel_lru_locks mdc
15411         cancel_lru_locks osc
15412         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15413         $LCTL set_param fail_loc=0x31b
15414         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15415         $LCTL set_param fail_loc=0
15416         rm -r $DIR/$tdir
15417 }
15418 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15419
15420 test_224a() { # LU-1039, MRP-303
15421         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15422
15423         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15424         $LCTL set_param fail_loc=0x508
15425         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15426         $LCTL set_param fail_loc=0
15427         df $DIR
15428 }
15429 run_test 224a "Don't panic on bulk IO failure"
15430
15431 test_224b() { # LU-1039, MRP-303
15432         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15433
15434         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15435         cancel_lru_locks osc
15436         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15437         $LCTL set_param fail_loc=0x515
15438         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15439         $LCTL set_param fail_loc=0
15440         df $DIR
15441 }
15442 run_test 224b "Don't panic on bulk IO failure"
15443
15444 test_224c() { # LU-6441
15445         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15446         remote_mds_nodsh && skip "remote MDS with nodsh"
15447
15448         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15449         save_writethrough $p
15450         set_cache writethrough on
15451
15452         local pages_per_rpc=$($LCTL get_param \
15453                                 osc.*.max_pages_per_rpc)
15454         local at_max=$($LCTL get_param -n at_max)
15455         local timeout=$($LCTL get_param -n timeout)
15456         local test_at="at_max"
15457         local param_at="$FSNAME.sys.at_max"
15458         local test_timeout="timeout"
15459         local param_timeout="$FSNAME.sys.timeout"
15460
15461         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15462
15463         set_persistent_param_and_check client "$test_at" "$param_at" 0
15464         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15465
15466         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15467         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15468         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15469         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15470         sync
15471         do_facet ost1 "$LCTL set_param fail_loc=0"
15472
15473         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15474         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15475                 $timeout
15476
15477         $LCTL set_param -n $pages_per_rpc
15478         restore_lustre_params < $p
15479         rm -f $p
15480 }
15481 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15482
15483 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15484 test_225a () {
15485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15486         if [ -z ${MDSSURVEY} ]; then
15487                 skip_env "mds-survey not found"
15488         fi
15489         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15490                 skip "Need MDS version at least 2.2.51"
15491
15492         local mds=$(facet_host $SINGLEMDS)
15493         local target=$(do_nodes $mds 'lctl dl' |
15494                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15495
15496         local cmd1="file_count=1000 thrhi=4"
15497         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15498         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15499         local cmd="$cmd1 $cmd2 $cmd3"
15500
15501         rm -f ${TMP}/mds_survey*
15502         echo + $cmd
15503         eval $cmd || error "mds-survey with zero-stripe failed"
15504         cat ${TMP}/mds_survey*
15505         rm -f ${TMP}/mds_survey*
15506 }
15507 run_test 225a "Metadata survey sanity with zero-stripe"
15508
15509 test_225b () {
15510         if [ -z ${MDSSURVEY} ]; then
15511                 skip_env "mds-survey not found"
15512         fi
15513         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15514                 skip "Need MDS version at least 2.2.51"
15515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15516         remote_mds_nodsh && skip "remote MDS with nodsh"
15517         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15518                 skip_env "Need to mount OST to test"
15519         fi
15520
15521         local mds=$(facet_host $SINGLEMDS)
15522         local target=$(do_nodes $mds 'lctl dl' |
15523                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15524
15525         local cmd1="file_count=1000 thrhi=4"
15526         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15527         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15528         local cmd="$cmd1 $cmd2 $cmd3"
15529
15530         rm -f ${TMP}/mds_survey*
15531         echo + $cmd
15532         eval $cmd || error "mds-survey with stripe_count failed"
15533         cat ${TMP}/mds_survey*
15534         rm -f ${TMP}/mds_survey*
15535 }
15536 run_test 225b "Metadata survey sanity with stripe_count = 1"
15537
15538 mcreate_path2fid () {
15539         local mode=$1
15540         local major=$2
15541         local minor=$3
15542         local name=$4
15543         local desc=$5
15544         local path=$DIR/$tdir/$name
15545         local fid
15546         local rc
15547         local fid_path
15548
15549         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15550                 error "cannot create $desc"
15551
15552         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15553         rc=$?
15554         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15555
15556         fid_path=$($LFS fid2path $MOUNT $fid)
15557         rc=$?
15558         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15559
15560         [ "$path" == "$fid_path" ] ||
15561                 error "fid2path returned $fid_path, expected $path"
15562
15563         echo "pass with $path and $fid"
15564 }
15565
15566 test_226a () {
15567         rm -rf $DIR/$tdir
15568         mkdir -p $DIR/$tdir
15569
15570         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15571         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15572         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15573         mcreate_path2fid 0040666 0 0 dir "directory"
15574         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15575         mcreate_path2fid 0100666 0 0 file "regular file"
15576         mcreate_path2fid 0120666 0 0 link "symbolic link"
15577         mcreate_path2fid 0140666 0 0 sock "socket"
15578 }
15579 run_test 226a "call path2fid and fid2path on files of all type"
15580
15581 test_226b () {
15582         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15583
15584         local MDTIDX=1
15585
15586         rm -rf $DIR/$tdir
15587         mkdir -p $DIR/$tdir
15588         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15589                 error "create remote directory failed"
15590         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15591         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15592                                 "character special file (null)"
15593         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15594                                 "character special file (no device)"
15595         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15596         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15597                                 "block special file (loop)"
15598         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15599         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15600         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15601 }
15602 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15603
15604 # LU-1299 Executing or running ldd on a truncated executable does not
15605 # cause an out-of-memory condition.
15606 test_227() {
15607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15608         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15609
15610         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15611         chmod +x $MOUNT/date
15612
15613         $MOUNT/date > /dev/null
15614         ldd $MOUNT/date > /dev/null
15615         rm -f $MOUNT/date
15616 }
15617 run_test 227 "running truncated executable does not cause OOM"
15618
15619 # LU-1512 try to reuse idle OI blocks
15620 test_228a() {
15621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15622         remote_mds_nodsh && skip "remote MDS with nodsh"
15623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15624
15625         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15626         local myDIR=$DIR/$tdir
15627
15628         mkdir -p $myDIR
15629         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15630         $LCTL set_param fail_loc=0x80001002
15631         createmany -o $myDIR/t- 10000
15632         $LCTL set_param fail_loc=0
15633         # The guard is current the largest FID holder
15634         touch $myDIR/guard
15635         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15636                     tr -d '[')
15637         local IDX=$(($SEQ % 64))
15638
15639         do_facet $SINGLEMDS sync
15640         # Make sure journal flushed.
15641         sleep 6
15642         local blk1=$(do_facet $SINGLEMDS \
15643                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15644                      grep Blockcount | awk '{print $4}')
15645
15646         # Remove old files, some OI blocks will become idle.
15647         unlinkmany $myDIR/t- 10000
15648         # Create new files, idle OI blocks should be reused.
15649         createmany -o $myDIR/t- 2000
15650         do_facet $SINGLEMDS sync
15651         # Make sure journal flushed.
15652         sleep 6
15653         local blk2=$(do_facet $SINGLEMDS \
15654                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15655                      grep Blockcount | awk '{print $4}')
15656
15657         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15658 }
15659 run_test 228a "try to reuse idle OI blocks"
15660
15661 test_228b() {
15662         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15663         remote_mds_nodsh && skip "remote MDS with nodsh"
15664         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15665
15666         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15667         local myDIR=$DIR/$tdir
15668
15669         mkdir -p $myDIR
15670         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15671         $LCTL set_param fail_loc=0x80001002
15672         createmany -o $myDIR/t- 10000
15673         $LCTL set_param fail_loc=0
15674         # The guard is current the largest FID holder
15675         touch $myDIR/guard
15676         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15677                     tr -d '[')
15678         local IDX=$(($SEQ % 64))
15679
15680         do_facet $SINGLEMDS sync
15681         # Make sure journal flushed.
15682         sleep 6
15683         local blk1=$(do_facet $SINGLEMDS \
15684                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15685                      grep Blockcount | awk '{print $4}')
15686
15687         # Remove old files, some OI blocks will become idle.
15688         unlinkmany $myDIR/t- 10000
15689
15690         # stop the MDT
15691         stop $SINGLEMDS || error "Fail to stop MDT."
15692         # remount the MDT
15693         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15694
15695         df $MOUNT || error "Fail to df."
15696         # Create new files, idle OI blocks should be reused.
15697         createmany -o $myDIR/t- 2000
15698         do_facet $SINGLEMDS sync
15699         # Make sure journal flushed.
15700         sleep 6
15701         local blk2=$(do_facet $SINGLEMDS \
15702                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15703                      grep Blockcount | awk '{print $4}')
15704
15705         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15706 }
15707 run_test 228b "idle OI blocks can be reused after MDT restart"
15708
15709 #LU-1881
15710 test_228c() {
15711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15712         remote_mds_nodsh && skip "remote MDS with nodsh"
15713         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15714
15715         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15716         local myDIR=$DIR/$tdir
15717
15718         mkdir -p $myDIR
15719         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15720         $LCTL set_param fail_loc=0x80001002
15721         # 20000 files can guarantee there are index nodes in the OI file
15722         createmany -o $myDIR/t- 20000
15723         $LCTL set_param fail_loc=0
15724         # The guard is current the largest FID holder
15725         touch $myDIR/guard
15726         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15727                     tr -d '[')
15728         local IDX=$(($SEQ % 64))
15729
15730         do_facet $SINGLEMDS sync
15731         # Make sure journal flushed.
15732         sleep 6
15733         local blk1=$(do_facet $SINGLEMDS \
15734                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15735                      grep Blockcount | awk '{print $4}')
15736
15737         # Remove old files, some OI blocks will become idle.
15738         unlinkmany $myDIR/t- 20000
15739         rm -f $myDIR/guard
15740         # The OI file should become empty now
15741
15742         # Create new files, idle OI blocks should be reused.
15743         createmany -o $myDIR/t- 2000
15744         do_facet $SINGLEMDS sync
15745         # Make sure journal flushed.
15746         sleep 6
15747         local blk2=$(do_facet $SINGLEMDS \
15748                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15749                      grep Blockcount | awk '{print $4}')
15750
15751         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15752 }
15753 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15754
15755 test_229() { # LU-2482, LU-3448
15756         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15757         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15758         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15759                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15760
15761         rm -f $DIR/$tfile
15762
15763         # Create a file with a released layout and stripe count 2.
15764         $MULTIOP $DIR/$tfile H2c ||
15765                 error "failed to create file with released layout"
15766
15767         $LFS getstripe -v $DIR/$tfile
15768
15769         local pattern=$($LFS getstripe -L $DIR/$tfile)
15770         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15771
15772         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15773                 error "getstripe"
15774         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15775         stat $DIR/$tfile || error "failed to stat released file"
15776
15777         chown $RUNAS_ID $DIR/$tfile ||
15778                 error "chown $RUNAS_ID $DIR/$tfile failed"
15779
15780         chgrp $RUNAS_ID $DIR/$tfile ||
15781                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15782
15783         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15784         rm $DIR/$tfile || error "failed to remove released file"
15785 }
15786 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15787
15788 test_230a() {
15789         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15790         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15791         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15792                 skip "Need MDS version at least 2.11.52"
15793
15794         local MDTIDX=1
15795
15796         test_mkdir $DIR/$tdir
15797         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15798         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15799         [ $mdt_idx -ne 0 ] &&
15800                 error "create local directory on wrong MDT $mdt_idx"
15801
15802         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15803                         error "create remote directory failed"
15804         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15805         [ $mdt_idx -ne $MDTIDX ] &&
15806                 error "create remote directory on wrong MDT $mdt_idx"
15807
15808         createmany -o $DIR/$tdir/test_230/t- 10 ||
15809                 error "create files on remote directory failed"
15810         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15811         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15812         rm -r $DIR/$tdir || error "unlink remote directory failed"
15813 }
15814 run_test 230a "Create remote directory and files under the remote directory"
15815
15816 test_230b() {
15817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15819         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15820                 skip "Need MDS version at least 2.11.52"
15821
15822         local MDTIDX=1
15823         local mdt_index
15824         local i
15825         local file
15826         local pid
15827         local stripe_count
15828         local migrate_dir=$DIR/$tdir/migrate_dir
15829         local other_dir=$DIR/$tdir/other_dir
15830
15831         test_mkdir $DIR/$tdir
15832         test_mkdir -i0 -c1 $migrate_dir
15833         test_mkdir -i0 -c1 $other_dir
15834         for ((i=0; i<10; i++)); do
15835                 mkdir -p $migrate_dir/dir_${i}
15836                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15837                         error "create files under remote dir failed $i"
15838         done
15839
15840         cp /etc/passwd $migrate_dir/$tfile
15841         cp /etc/passwd $other_dir/$tfile
15842         chattr +SAD $migrate_dir
15843         chattr +SAD $migrate_dir/$tfile
15844
15845         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15846         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15847         local old_dir_mode=$(stat -c%f $migrate_dir)
15848         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15849
15850         mkdir -p $migrate_dir/dir_default_stripe2
15851         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15852         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15853
15854         mkdir -p $other_dir
15855         ln $migrate_dir/$tfile $other_dir/luna
15856         ln $migrate_dir/$tfile $migrate_dir/sofia
15857         ln $other_dir/$tfile $migrate_dir/david
15858         ln -s $migrate_dir/$tfile $other_dir/zachary
15859         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15860         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15861
15862         $LFS migrate -m $MDTIDX $migrate_dir ||
15863                 error "fails on migrating remote dir to MDT1"
15864
15865         echo "migratate to MDT1, then checking.."
15866         for ((i = 0; i < 10; i++)); do
15867                 for file in $(find $migrate_dir/dir_${i}); do
15868                         mdt_index=$($LFS getstripe -m $file)
15869                         [ $mdt_index == $MDTIDX ] ||
15870                                 error "$file is not on MDT${MDTIDX}"
15871                 done
15872         done
15873
15874         # the multiple link file should still in MDT0
15875         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15876         [ $mdt_index == 0 ] ||
15877                 error "$file is not on MDT${MDTIDX}"
15878
15879         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15880         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15881                 error " expect $old_dir_flag get $new_dir_flag"
15882
15883         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15884         [ "$old_file_flag" = "$new_file_flag" ] ||
15885                 error " expect $old_file_flag get $new_file_flag"
15886
15887         local new_dir_mode=$(stat -c%f $migrate_dir)
15888         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15889                 error "expect mode $old_dir_mode get $new_dir_mode"
15890
15891         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15892         [ "$old_file_mode" = "$new_file_mode" ] ||
15893                 error "expect mode $old_file_mode get $new_file_mode"
15894
15895         diff /etc/passwd $migrate_dir/$tfile ||
15896                 error "$tfile different after migration"
15897
15898         diff /etc/passwd $other_dir/luna ||
15899                 error "luna different after migration"
15900
15901         diff /etc/passwd $migrate_dir/sofia ||
15902                 error "sofia different after migration"
15903
15904         diff /etc/passwd $migrate_dir/david ||
15905                 error "david different after migration"
15906
15907         diff /etc/passwd $other_dir/zachary ||
15908                 error "zachary different after migration"
15909
15910         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15911                 error "${tfile}_ln different after migration"
15912
15913         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15914                 error "${tfile}_ln_other different after migration"
15915
15916         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15917         [ $stripe_count = 2 ] ||
15918                 error "dir strpe_count $d != 2 after migration."
15919
15920         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15921         [ $stripe_count = 2 ] ||
15922                 error "file strpe_count $d != 2 after migration."
15923
15924         #migrate back to MDT0
15925         MDTIDX=0
15926
15927         $LFS migrate -m $MDTIDX $migrate_dir ||
15928                 error "fails on migrating remote dir to MDT0"
15929
15930         echo "migrate back to MDT0, checking.."
15931         for file in $(find $migrate_dir); do
15932                 mdt_index=$($LFS getstripe -m $file)
15933                 [ $mdt_index == $MDTIDX ] ||
15934                         error "$file is not on MDT${MDTIDX}"
15935         done
15936
15937         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15938         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15939                 error " expect $old_dir_flag get $new_dir_flag"
15940
15941         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15942         [ "$old_file_flag" = "$new_file_flag" ] ||
15943                 error " expect $old_file_flag get $new_file_flag"
15944
15945         local new_dir_mode=$(stat -c%f $migrate_dir)
15946         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15947                 error "expect mode $old_dir_mode get $new_dir_mode"
15948
15949         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15950         [ "$old_file_mode" = "$new_file_mode" ] ||
15951                 error "expect mode $old_file_mode get $new_file_mode"
15952
15953         diff /etc/passwd ${migrate_dir}/$tfile ||
15954                 error "$tfile different after migration"
15955
15956         diff /etc/passwd ${other_dir}/luna ||
15957                 error "luna different after migration"
15958
15959         diff /etc/passwd ${migrate_dir}/sofia ||
15960                 error "sofia different after migration"
15961
15962         diff /etc/passwd ${other_dir}/zachary ||
15963                 error "zachary different after migration"
15964
15965         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15966                 error "${tfile}_ln different after migration"
15967
15968         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15969                 error "${tfile}_ln_other different after migration"
15970
15971         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15972         [ $stripe_count = 2 ] ||
15973                 error "dir strpe_count $d != 2 after migration."
15974
15975         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15976         [ $stripe_count = 2 ] ||
15977                 error "file strpe_count $d != 2 after migration."
15978
15979         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15980 }
15981 run_test 230b "migrate directory"
15982
15983 test_230c() {
15984         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15985         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15986         remote_mds_nodsh && skip "remote MDS with nodsh"
15987         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15988                 skip "Need MDS version at least 2.11.52"
15989
15990         local MDTIDX=1
15991         local total=3
15992         local mdt_index
15993         local file
15994         local migrate_dir=$DIR/$tdir/migrate_dir
15995
15996         #If migrating directory fails in the middle, all entries of
15997         #the directory is still accessiable.
15998         test_mkdir $DIR/$tdir
15999         test_mkdir -i0 -c1 $migrate_dir
16000         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16001         stat $migrate_dir
16002         createmany -o $migrate_dir/f $total ||
16003                 error "create files under ${migrate_dir} failed"
16004
16005         # fail after migrating top dir, and this will fail only once, so the
16006         # first sub file migration will fail (currently f3), others succeed.
16007         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16008         do_facet mds1 lctl set_param fail_loc=0x1801
16009         local t=$(ls $migrate_dir | wc -l)
16010         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16011                 error "migrate should fail"
16012         local u=$(ls $migrate_dir | wc -l)
16013         [ "$u" == "$t" ] || error "$u != $t during migration"
16014
16015         # add new dir/file should succeed
16016         mkdir $migrate_dir/dir ||
16017                 error "mkdir failed under migrating directory"
16018         touch $migrate_dir/file ||
16019                 error "create file failed under migrating directory"
16020
16021         # add file with existing name should fail
16022         for file in $migrate_dir/f*; do
16023                 stat $file > /dev/null || error "stat $file failed"
16024                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16025                         error "open(O_CREAT|O_EXCL) $file should fail"
16026                 $MULTIOP $file m && error "create $file should fail"
16027                 touch $DIR/$tdir/remote_dir/$tfile ||
16028                         error "touch $tfile failed"
16029                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16030                         error "link $file should fail"
16031                 mdt_index=$($LFS getstripe -m $file)
16032                 if [ $mdt_index == 0 ]; then
16033                         # file failed to migrate is not allowed to rename to
16034                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16035                                 error "rename to $file should fail"
16036                 else
16037                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16038                                 error "rename to $file failed"
16039                 fi
16040                 echo hello >> $file || error "write $file failed"
16041         done
16042
16043         # resume migration with different options should fail
16044         $LFS migrate -m 0 $migrate_dir &&
16045                 error "migrate -m 0 $migrate_dir should fail"
16046
16047         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16048                 error "migrate -c 2 $migrate_dir should fail"
16049
16050         # resume migration should succeed
16051         $LFS migrate -m $MDTIDX $migrate_dir ||
16052                 error "migrate $migrate_dir failed"
16053
16054         echo "Finish migration, then checking.."
16055         for file in $(find $migrate_dir); do
16056                 mdt_index=$($LFS getstripe -m $file)
16057                 [ $mdt_index == $MDTIDX ] ||
16058                         error "$file is not on MDT${MDTIDX}"
16059         done
16060
16061         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16062 }
16063 run_test 230c "check directory accessiblity if migration failed"
16064
16065 test_230d() {
16066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16068         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16069                 skip "Need MDS version at least 2.11.52"
16070         # LU-11235
16071         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16072
16073         local migrate_dir=$DIR/$tdir/migrate_dir
16074         local old_index
16075         local new_index
16076         local old_count
16077         local new_count
16078         local new_hash
16079         local mdt_index
16080         local i
16081         local j
16082
16083         old_index=$((RANDOM % MDSCOUNT))
16084         old_count=$((MDSCOUNT - old_index))
16085         new_index=$((RANDOM % MDSCOUNT))
16086         new_count=$((MDSCOUNT - new_index))
16087         new_hash="all_char"
16088
16089         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16090         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16091
16092         test_mkdir $DIR/$tdir
16093         test_mkdir -i $old_index -c $old_count $migrate_dir
16094
16095         for ((i=0; i<100; i++)); do
16096                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16097                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16098                         error "create files under remote dir failed $i"
16099         done
16100
16101         echo -n "Migrate from MDT$old_index "
16102         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16103         echo -n "to MDT$new_index"
16104         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16105         echo
16106
16107         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16108         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16109                 error "migrate remote dir error"
16110
16111         echo "Finish migration, then checking.."
16112         for file in $(find $migrate_dir); do
16113                 mdt_index=$($LFS getstripe -m $file)
16114                 if [ $mdt_index -lt $new_index ] ||
16115                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16116                         error "$file is on MDT$mdt_index"
16117                 fi
16118         done
16119
16120         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16121 }
16122 run_test 230d "check migrate big directory"
16123
16124 test_230e() {
16125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16126         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16127         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16128                 skip "Need MDS version at least 2.11.52"
16129
16130         local i
16131         local j
16132         local a_fid
16133         local b_fid
16134
16135         mkdir -p $DIR/$tdir
16136         mkdir $DIR/$tdir/migrate_dir
16137         mkdir $DIR/$tdir/other_dir
16138         touch $DIR/$tdir/migrate_dir/a
16139         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16140         ls $DIR/$tdir/other_dir
16141
16142         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16143                 error "migrate dir fails"
16144
16145         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16146         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16147
16148         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16149         [ $mdt_index == 0 ] || error "a is not on MDT0"
16150
16151         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16152                 error "migrate dir fails"
16153
16154         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16155         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16156
16157         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16158         [ $mdt_index == 1 ] || error "a is not on MDT1"
16159
16160         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16161         [ $mdt_index == 1 ] || error "b is not on MDT1"
16162
16163         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16164         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16165
16166         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16167
16168         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16169 }
16170 run_test 230e "migrate mulitple local link files"
16171
16172 test_230f() {
16173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16174         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16175         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16176                 skip "Need MDS version at least 2.11.52"
16177
16178         local a_fid
16179         local ln_fid
16180
16181         mkdir -p $DIR/$tdir
16182         mkdir $DIR/$tdir/migrate_dir
16183         $LFS mkdir -i1 $DIR/$tdir/other_dir
16184         touch $DIR/$tdir/migrate_dir/a
16185         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16186         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16187         ls $DIR/$tdir/other_dir
16188
16189         # a should be migrated to MDT1, since no other links on MDT0
16190         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16191                 error "#1 migrate dir fails"
16192         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16193         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16194         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16195         [ $mdt_index == 1 ] || error "a is not on MDT1"
16196
16197         # a should stay on MDT1, because it is a mulitple link file
16198         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16199                 error "#2 migrate dir fails"
16200         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16201         [ $mdt_index == 1 ] || error "a is not on MDT1"
16202
16203         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16204                 error "#3 migrate dir fails"
16205
16206         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16207         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16208         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16209
16210         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16211         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16212
16213         # a should be migrated to MDT0, since no other links on MDT1
16214         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16215                 error "#4 migrate dir fails"
16216         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16217         [ $mdt_index == 0 ] || error "a is not on MDT0"
16218
16219         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16220 }
16221 run_test 230f "migrate mulitple remote link files"
16222
16223 test_230g() {
16224         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16225         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16226         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16227                 skip "Need MDS version at least 2.11.52"
16228
16229         mkdir -p $DIR/$tdir/migrate_dir
16230
16231         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16232                 error "migrating dir to non-exist MDT succeeds"
16233         true
16234 }
16235 run_test 230g "migrate dir to non-exist MDT"
16236
16237 test_230h() {
16238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16239         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16240         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16241                 skip "Need MDS version at least 2.11.52"
16242
16243         local mdt_index
16244
16245         mkdir -p $DIR/$tdir/migrate_dir
16246
16247         $LFS migrate -m1 $DIR &&
16248                 error "migrating mountpoint1 should fail"
16249
16250         $LFS migrate -m1 $DIR/$tdir/.. &&
16251                 error "migrating mountpoint2 should fail"
16252
16253         # same as mv
16254         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16255                 error "migrating $tdir/migrate_dir/.. should fail"
16256
16257         true
16258 }
16259 run_test 230h "migrate .. and root"
16260
16261 test_230i() {
16262         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16263         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16264         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16265                 skip "Need MDS version at least 2.11.52"
16266
16267         mkdir -p $DIR/$tdir/migrate_dir
16268
16269         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16270                 error "migration fails with a tailing slash"
16271
16272         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16273                 error "migration fails with two tailing slashes"
16274 }
16275 run_test 230i "lfs migrate -m tolerates trailing slashes"
16276
16277 test_230j() {
16278         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16279         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16280                 skip "Need MDS version at least 2.11.52"
16281
16282         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16283         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16284                 error "create $tfile failed"
16285         cat /etc/passwd > $DIR/$tdir/$tfile
16286
16287         $LFS migrate -m 1 $DIR/$tdir
16288
16289         cmp /etc/passwd $DIR/$tdir/$tfile ||
16290                 error "DoM file mismatch after migration"
16291 }
16292 run_test 230j "DoM file data not changed after dir migration"
16293
16294 test_230k() {
16295         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16296         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16297                 skip "Need MDS version at least 2.11.56"
16298
16299         local total=20
16300         local files_on_starting_mdt=0
16301
16302         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16303         $LFS getdirstripe $DIR/$tdir
16304         for i in $(seq $total); do
16305                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16306                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16307                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16308         done
16309
16310         echo "$files_on_starting_mdt files on MDT0"
16311
16312         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16313         $LFS getdirstripe $DIR/$tdir
16314
16315         files_on_starting_mdt=0
16316         for i in $(seq $total); do
16317                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16318                         error "file $tfile.$i mismatch after migration"
16319                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16320                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16321         done
16322
16323         echo "$files_on_starting_mdt files on MDT1 after migration"
16324         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16325
16326         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16327         $LFS getdirstripe $DIR/$tdir
16328
16329         files_on_starting_mdt=0
16330         for i in $(seq $total); do
16331                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16332                         error "file $tfile.$i mismatch after 2nd migration"
16333                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16334                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16335         done
16336
16337         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16338         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16339
16340         true
16341 }
16342 run_test 230k "file data not changed after dir migration"
16343
16344 test_230l() {
16345         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16346         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16347                 skip "Need MDS version at least 2.11.56"
16348
16349         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16350         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16351                 error "create files under remote dir failed $i"
16352         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16353 }
16354 run_test 230l "readdir between MDTs won't crash"
16355
16356 test_231a()
16357 {
16358         # For simplicity this test assumes that max_pages_per_rpc
16359         # is the same across all OSCs
16360         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16361         local bulk_size=$((max_pages * PAGE_SIZE))
16362         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16363                                        head -n 1)
16364
16365         mkdir -p $DIR/$tdir
16366         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16367                 error "failed to set stripe with -S ${brw_size}M option"
16368
16369         # clear the OSC stats
16370         $LCTL set_param osc.*.stats=0 &>/dev/null
16371         stop_writeback
16372
16373         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16374         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16375                 oflag=direct &>/dev/null || error "dd failed"
16376
16377         sync; sleep 1; sync # just to be safe
16378         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16379         if [ x$nrpcs != "x1" ]; then
16380                 $LCTL get_param osc.*.stats
16381                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16382         fi
16383
16384         start_writeback
16385         # Drop the OSC cache, otherwise we will read from it
16386         cancel_lru_locks osc
16387
16388         # clear the OSC stats
16389         $LCTL set_param osc.*.stats=0 &>/dev/null
16390
16391         # Client reads $bulk_size.
16392         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16393                 iflag=direct &>/dev/null || error "dd failed"
16394
16395         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16396         if [ x$nrpcs != "x1" ]; then
16397                 $LCTL get_param osc.*.stats
16398                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16399         fi
16400 }
16401 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16402
16403 test_231b() {
16404         mkdir -p $DIR/$tdir
16405         local i
16406         for i in {0..1023}; do
16407                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16408                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16409                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16410         done
16411         sync
16412 }
16413 run_test 231b "must not assert on fully utilized OST request buffer"
16414
16415 test_232a() {
16416         mkdir -p $DIR/$tdir
16417         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16418
16419         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16420         do_facet ost1 $LCTL set_param fail_loc=0x31c
16421
16422         # ignore dd failure
16423         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16424
16425         do_facet ost1 $LCTL set_param fail_loc=0
16426         umount_client $MOUNT || error "umount failed"
16427         mount_client $MOUNT || error "mount failed"
16428         stop ost1 || error "cannot stop ost1"
16429         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16430 }
16431 run_test 232a "failed lock should not block umount"
16432
16433 test_232b() {
16434         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16435                 skip "Need MDS version at least 2.10.58"
16436
16437         mkdir -p $DIR/$tdir
16438         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16439         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16440         sync
16441         cancel_lru_locks osc
16442
16443         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16444         do_facet ost1 $LCTL set_param fail_loc=0x31c
16445
16446         # ignore failure
16447         $LFS data_version $DIR/$tdir/$tfile || true
16448
16449         do_facet ost1 $LCTL set_param fail_loc=0
16450         umount_client $MOUNT || error "umount failed"
16451         mount_client $MOUNT || error "mount failed"
16452         stop ost1 || error "cannot stop ost1"
16453         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16454 }
16455 run_test 232b "failed data version lock should not block umount"
16456
16457 test_233a() {
16458         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16459                 skip "Need MDS version at least 2.3.64"
16460         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16461
16462         local fid=$($LFS path2fid $MOUNT)
16463
16464         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16465                 error "cannot access $MOUNT using its FID '$fid'"
16466 }
16467 run_test 233a "checking that OBF of the FS root succeeds"
16468
16469 test_233b() {
16470         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16471                 skip "Need MDS version at least 2.5.90"
16472         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16473
16474         local fid=$($LFS path2fid $MOUNT/.lustre)
16475
16476         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16477                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16478
16479         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16480         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16481                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16482 }
16483 run_test 233b "checking that OBF of the FS .lustre succeeds"
16484
16485 test_234() {
16486         local p="$TMP/sanityN-$TESTNAME.parameters"
16487         save_lustre_params client "llite.*.xattr_cache" > $p
16488         lctl set_param llite.*.xattr_cache 1 ||
16489                 skip_env "xattr cache is not supported"
16490
16491         mkdir -p $DIR/$tdir || error "mkdir failed"
16492         touch $DIR/$tdir/$tfile || error "touch failed"
16493         # OBD_FAIL_LLITE_XATTR_ENOMEM
16494         $LCTL set_param fail_loc=0x1405
16495         getfattr -n user.attr $DIR/$tdir/$tfile &&
16496                 error "getfattr should have failed with ENOMEM"
16497         $LCTL set_param fail_loc=0x0
16498         rm -rf $DIR/$tdir
16499
16500         restore_lustre_params < $p
16501         rm -f $p
16502 }
16503 run_test 234 "xattr cache should not crash on ENOMEM"
16504
16505 test_235() {
16506         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16507                 skip "Need MDS version at least 2.4.52"
16508
16509         flock_deadlock $DIR/$tfile
16510         local RC=$?
16511         case $RC in
16512                 0)
16513                 ;;
16514                 124) error "process hangs on a deadlock"
16515                 ;;
16516                 *) error "error executing flock_deadlock $DIR/$tfile"
16517                 ;;
16518         esac
16519 }
16520 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16521
16522 #LU-2935
16523 test_236() {
16524         check_swap_layouts_support
16525
16526         local ref1=/etc/passwd
16527         local ref2=/etc/group
16528         local file1=$DIR/$tdir/f1
16529         local file2=$DIR/$tdir/f2
16530
16531         test_mkdir -c1 $DIR/$tdir
16532         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16533         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16534         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16535         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16536         local fd=$(free_fd)
16537         local cmd="exec $fd<>$file2"
16538         eval $cmd
16539         rm $file2
16540         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16541                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16542         cmd="exec $fd>&-"
16543         eval $cmd
16544         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16545
16546         #cleanup
16547         rm -rf $DIR/$tdir
16548 }
16549 run_test 236 "Layout swap on open unlinked file"
16550
16551 # LU-4659 linkea consistency
16552 test_238() {
16553         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16554                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16555                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16556                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16557
16558         touch $DIR/$tfile
16559         ln $DIR/$tfile $DIR/$tfile.lnk
16560         touch $DIR/$tfile.new
16561         mv $DIR/$tfile.new $DIR/$tfile
16562         local fid1=$($LFS path2fid $DIR/$tfile)
16563         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16564         local path1=$($LFS fid2path $FSNAME "$fid1")
16565         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16566         local path2=$($LFS fid2path $FSNAME "$fid2")
16567         [ $tfile.lnk == $path2 ] ||
16568                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16569         rm -f $DIR/$tfile*
16570 }
16571 run_test 238 "Verify linkea consistency"
16572
16573 test_239A() { # was test_239
16574         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16575                 skip "Need MDS version at least 2.5.60"
16576
16577         local list=$(comma_list $(mdts_nodes))
16578
16579         mkdir -p $DIR/$tdir
16580         createmany -o $DIR/$tdir/f- 5000
16581         unlinkmany $DIR/$tdir/f- 5000
16582         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16583                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16584         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16585                         osp.*MDT*.sync_in_flight" | calc_sum)
16586         [ "$changes" -eq 0 ] || error "$changes not synced"
16587 }
16588 run_test 239A "osp_sync test"
16589
16590 test_239a() { #LU-5297
16591         remote_mds_nodsh && skip "remote MDS with nodsh"
16592
16593         touch $DIR/$tfile
16594         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16595         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16596         chgrp $RUNAS_GID $DIR/$tfile
16597         wait_delete_completed
16598 }
16599 run_test 239a "process invalid osp sync record correctly"
16600
16601 test_239b() { #LU-5297
16602         remote_mds_nodsh && skip "remote MDS with nodsh"
16603
16604         touch $DIR/$tfile1
16605         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16606         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16607         chgrp $RUNAS_GID $DIR/$tfile1
16608         wait_delete_completed
16609         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16610         touch $DIR/$tfile2
16611         chgrp $RUNAS_GID $DIR/$tfile2
16612         wait_delete_completed
16613 }
16614 run_test 239b "process osp sync record with ENOMEM error correctly"
16615
16616 test_240() {
16617         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16618         remote_mds_nodsh && skip "remote MDS with nodsh"
16619
16620         mkdir -p $DIR/$tdir
16621
16622         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16623                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16624         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16625                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16626
16627         umount_client $MOUNT || error "umount failed"
16628         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16629         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16630         mount_client $MOUNT || error "failed to mount client"
16631
16632         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16633         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16634 }
16635 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16636
16637 test_241_bio() {
16638         local count=$1
16639         local bsize=$2
16640
16641         for LOOP in $(seq $count); do
16642                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16643                 cancel_lru_locks $OSC || true
16644         done
16645 }
16646
16647 test_241_dio() {
16648         local count=$1
16649         local bsize=$2
16650
16651         for LOOP in $(seq $1); do
16652                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16653                         2>/dev/null
16654         done
16655 }
16656
16657 test_241a() { # was test_241
16658         local bsize=$PAGE_SIZE
16659
16660         (( bsize < 40960 )) && bsize=40960
16661         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16662         ls -la $DIR/$tfile
16663         cancel_lru_locks $OSC
16664         test_241_bio 1000 $bsize &
16665         PID=$!
16666         test_241_dio 1000 $bsize
16667         wait $PID
16668 }
16669 run_test 241a "bio vs dio"
16670
16671 test_241b() {
16672         local bsize=$PAGE_SIZE
16673
16674         (( bsize < 40960 )) && bsize=40960
16675         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16676         ls -la $DIR/$tfile
16677         test_241_dio 1000 $bsize &
16678         PID=$!
16679         test_241_dio 1000 $bsize
16680         wait $PID
16681 }
16682 run_test 241b "dio vs dio"
16683
16684 test_242() {
16685         remote_mds_nodsh && skip "remote MDS with nodsh"
16686
16687         mkdir -p $DIR/$tdir
16688         touch $DIR/$tdir/$tfile
16689
16690         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16691         do_facet mds1 lctl set_param fail_loc=0x105
16692         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16693
16694         do_facet mds1 lctl set_param fail_loc=0
16695         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16696 }
16697 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16698
16699 test_243()
16700 {
16701         test_mkdir $DIR/$tdir
16702         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16703 }
16704 run_test 243 "various group lock tests"
16705
16706 test_244()
16707 {
16708         test_mkdir $DIR/$tdir
16709         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16710         sendfile_grouplock $DIR/$tdir/$tfile || \
16711                 error "sendfile+grouplock failed"
16712         rm -rf $DIR/$tdir
16713 }
16714 run_test 244 "sendfile with group lock tests"
16715
16716 test_245() {
16717         local flagname="multi_mod_rpcs"
16718         local connect_data_name="max_mod_rpcs"
16719         local out
16720
16721         # check if multiple modify RPCs flag is set
16722         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16723                 grep "connect_flags:")
16724         echo "$out"
16725
16726         echo "$out" | grep -qw $flagname
16727         if [ $? -ne 0 ]; then
16728                 echo "connect flag $flagname is not set"
16729                 return
16730         fi
16731
16732         # check if multiple modify RPCs data is set
16733         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16734         echo "$out"
16735
16736         echo "$out" | grep -qw $connect_data_name ||
16737                 error "import should have connect data $connect_data_name"
16738 }
16739 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16740
16741 test_246() { # LU-7371
16742         remote_ost_nodsh && skip "remote OST with nodsh"
16743         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16744                 skip "Need OST version >= 2.7.62"
16745
16746         do_facet ost1 $LCTL set_param fail_val=4095
16747 #define OBD_FAIL_OST_READ_SIZE          0x234
16748         do_facet ost1 $LCTL set_param fail_loc=0x234
16749         $LFS setstripe $DIR/$tfile -i 0 -c 1
16750         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16751         cancel_lru_locks $FSNAME-OST0000
16752         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16753 }
16754 run_test 246 "Read file of size 4095 should return right length"
16755
16756 cleanup_247() {
16757         local submount=$1
16758
16759         trap 0
16760         umount_client $submount
16761         rmdir $submount
16762 }
16763
16764 test_247a() {
16765         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16766                 grep -q subtree ||
16767                 skip_env "Fileset feature is not supported"
16768
16769         local submount=${MOUNT}_$tdir
16770
16771         mkdir $MOUNT/$tdir
16772         mkdir -p $submount || error "mkdir $submount failed"
16773         FILESET="$FILESET/$tdir" mount_client $submount ||
16774                 error "mount $submount failed"
16775         trap "cleanup_247 $submount" EXIT
16776         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16777         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16778                 error "read $MOUNT/$tdir/$tfile failed"
16779         cleanup_247 $submount
16780 }
16781 run_test 247a "mount subdir as fileset"
16782
16783 test_247b() {
16784         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16785                 skip_env "Fileset feature is not supported"
16786
16787         local submount=${MOUNT}_$tdir
16788
16789         rm -rf $MOUNT/$tdir
16790         mkdir -p $submount || error "mkdir $submount failed"
16791         SKIP_FILESET=1
16792         FILESET="$FILESET/$tdir" mount_client $submount &&
16793                 error "mount $submount should fail"
16794         rmdir $submount
16795 }
16796 run_test 247b "mount subdir that dose not exist"
16797
16798 test_247c() {
16799         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16800                 skip_env "Fileset feature is not supported"
16801
16802         local submount=${MOUNT}_$tdir
16803
16804         mkdir -p $MOUNT/$tdir/dir1
16805         mkdir -p $submount || error "mkdir $submount failed"
16806         trap "cleanup_247 $submount" EXIT
16807         FILESET="$FILESET/$tdir" mount_client $submount ||
16808                 error "mount $submount failed"
16809         local fid=$($LFS path2fid $MOUNT/)
16810         $LFS fid2path $submount $fid && error "fid2path should fail"
16811         cleanup_247 $submount
16812 }
16813 run_test 247c "running fid2path outside root"
16814
16815 test_247d() {
16816         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16817                 skip "Fileset feature is not supported"
16818
16819         local submount=${MOUNT}_$tdir
16820
16821         mkdir -p $MOUNT/$tdir/dir1
16822         mkdir -p $submount || error "mkdir $submount failed"
16823         FILESET="$FILESET/$tdir" mount_client $submount ||
16824                 error "mount $submount failed"
16825         trap "cleanup_247 $submount" EXIT
16826         local fid=$($LFS path2fid $submount/dir1)
16827         $LFS fid2path $submount $fid || error "fid2path should succeed"
16828         cleanup_247 $submount
16829 }
16830 run_test 247d "running fid2path inside root"
16831
16832 # LU-8037
16833 test_247e() {
16834         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16835                 grep -q subtree ||
16836                 skip "Fileset feature is not supported"
16837
16838         local submount=${MOUNT}_$tdir
16839
16840         mkdir $MOUNT/$tdir
16841         mkdir -p $submount || error "mkdir $submount failed"
16842         FILESET="$FILESET/.." mount_client $submount &&
16843                 error "mount $submount should fail"
16844         rmdir $submount
16845 }
16846 run_test 247e "mount .. as fileset"
16847
16848 test_248() {
16849         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16850         [ -z "$fast_read_sav" ] && skip "no fast read support"
16851
16852         # create a large file for fast read verification
16853         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16854
16855         # make sure the file is created correctly
16856         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16857                 { rm -f $DIR/$tfile; skip "file creation error"; }
16858
16859         echo "Test 1: verify that fast read is 4 times faster on cache read"
16860
16861         # small read with fast read enabled
16862         $LCTL set_param -n llite.*.fast_read=1
16863         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16864                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16865                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16866         # small read with fast read disabled
16867         $LCTL set_param -n llite.*.fast_read=0
16868         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16869                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16870                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16871
16872         # verify that fast read is 4 times faster for cache read
16873         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16874                 error_not_in_vm "fast read was not 4 times faster: " \
16875                            "$t_fast vs $t_slow"
16876
16877         echo "Test 2: verify the performance between big and small read"
16878         $LCTL set_param -n llite.*.fast_read=1
16879
16880         # 1k non-cache read
16881         cancel_lru_locks osc
16882         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16883                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16884                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16885
16886         # 1M non-cache read
16887         cancel_lru_locks osc
16888         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16889                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16890                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16891
16892         # verify that big IO is not 4 times faster than small IO
16893         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16894                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16895
16896         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16897         rm -f $DIR/$tfile
16898 }
16899 run_test 248 "fast read verification"
16900
16901 test_249() { # LU-7890
16902         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16903                 skip "Need at least version 2.8.54"
16904
16905         rm -f $DIR/$tfile
16906         $LFS setstripe -c 1 $DIR/$tfile
16907         # Offset 2T == 4k * 512M
16908         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16909                 error "dd to 2T offset failed"
16910 }
16911 run_test 249 "Write above 2T file size"
16912
16913 test_250() {
16914         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16915          && skip "no 16TB file size limit on ZFS"
16916
16917         $LFS setstripe -c 1 $DIR/$tfile
16918         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16919         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16920         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16921         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16922                 conv=notrunc,fsync && error "append succeeded"
16923         return 0
16924 }
16925 run_test 250 "Write above 16T limit"
16926
16927 test_251() {
16928         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16929
16930         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16931         #Skip once - writing the first stripe will succeed
16932         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16933         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16934                 error "short write happened"
16935
16936         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16937         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16938                 error "short read happened"
16939
16940         rm -f $DIR/$tfile
16941 }
16942 run_test 251 "Handling short read and write correctly"
16943
16944 test_252() {
16945         remote_mds_nodsh && skip "remote MDS with nodsh"
16946         remote_ost_nodsh && skip "remote OST with nodsh"
16947         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16948                 skip_env "ldiskfs only test"
16949         fi
16950
16951         local tgt
16952         local dev
16953         local out
16954         local uuid
16955         local num
16956         local gen
16957
16958         # check lr_reader on OST0000
16959         tgt=ost1
16960         dev=$(facet_device $tgt)
16961         out=$(do_facet $tgt $LR_READER $dev)
16962         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16963         echo "$out"
16964         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16965         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16966                 error "Invalid uuid returned by $LR_READER on target $tgt"
16967         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16968
16969         # check lr_reader -c on MDT0000
16970         tgt=mds1
16971         dev=$(facet_device $tgt)
16972         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16973                 skip "$LR_READER does not support additional options"
16974         fi
16975         out=$(do_facet $tgt $LR_READER -c $dev)
16976         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16977         echo "$out"
16978         num=$(echo "$out" | grep -c "mdtlov")
16979         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16980                 error "Invalid number of mdtlov clients returned by $LR_READER"
16981         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16982
16983         # check lr_reader -cr on MDT0000
16984         out=$(do_facet $tgt $LR_READER -cr $dev)
16985         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16986         echo "$out"
16987         echo "$out" | grep -q "^reply_data:$" ||
16988                 error "$LR_READER should have returned 'reply_data' section"
16989         num=$(echo "$out" | grep -c "client_generation")
16990         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16991 }
16992 run_test 252 "check lr_reader tool"
16993
16994 test_253() {
16995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16996         remote_mds_nodsh && skip "remote MDS with nodsh"
16997         remote_mgs_nodsh && skip "remote MGS with nodsh"
16998
16999         local ostidx=0
17000         local rc=0
17001         local ost_name=$(ostname_from_index $ostidx)
17002
17003         # on the mdt's osc
17004         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17005         do_facet $SINGLEMDS $LCTL get_param -n \
17006                 osp.$mdtosc_proc1.reserved_mb_high ||
17007                 skip  "remote MDS does not support reserved_mb_high"
17008
17009         rm -rf $DIR/$tdir
17010         wait_mds_ost_sync
17011         wait_delete_completed
17012         mkdir $DIR/$tdir
17013
17014         if ! combined_mgs_mds ; then
17015                 mount_mgs_client
17016         fi
17017         pool_add $TESTNAME || error "Pool creation failed"
17018         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17019
17020         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17021                 error "Setstripe failed"
17022
17023         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17024
17025         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17026                     grep "watermarks")
17027         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17028
17029         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17030                         osp.$mdtosc_proc1.prealloc_status)
17031         echo "prealloc_status $oa_status"
17032
17033         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17034                 error "File creation should fail"
17035
17036         #object allocation was stopped, but we still able to append files
17037         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17038                 oflag=append || error "Append failed"
17039
17040         rm -f $DIR/$tdir/$tfile.0
17041
17042         # For this test, we want to delete the files we created to go out of
17043         # space but leave the watermark, so we remain nearly out of space
17044         ost_watermarks_enospc_delete_files $tfile $ostidx
17045
17046         wait_delete_completed
17047
17048         sleep_maxage
17049
17050         for i in $(seq 10 12); do
17051                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17052                         2>/dev/null || error "File creation failed after rm"
17053         done
17054
17055         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17056                         osp.$mdtosc_proc1.prealloc_status)
17057         echo "prealloc_status $oa_status"
17058
17059         if (( oa_status != 0 )); then
17060                 error "Object allocation still disable after rm"
17061         fi
17062
17063         if ! combined_mgs_mds ; then
17064                 umount_mgs_client
17065         fi
17066 }
17067 run_test 253 "Check object allocation limit"
17068
17069 test_254() {
17070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17071         remote_mds_nodsh && skip "remote MDS with nodsh"
17072         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17073                 skip "MDS does not support changelog_size"
17074
17075         local cl_user
17076         local MDT0=$(facet_svc $SINGLEMDS)
17077
17078         changelog_register || error "changelog_register failed"
17079
17080         changelog_clear 0 || error "changelog_clear failed"
17081
17082         local size1=$(do_facet $SINGLEMDS \
17083                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17084         echo "Changelog size $size1"
17085
17086         rm -rf $DIR/$tdir
17087         $LFS mkdir -i 0 $DIR/$tdir
17088         # change something
17089         mkdir -p $DIR/$tdir/pics/2008/zachy
17090         touch $DIR/$tdir/pics/2008/zachy/timestamp
17091         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17092         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17093         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17094         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17095         rm $DIR/$tdir/pics/desktop.jpg
17096
17097         local size2=$(do_facet $SINGLEMDS \
17098                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17099         echo "Changelog size after work $size2"
17100
17101         (( $size2 > $size1 )) ||
17102                 error "new Changelog size=$size2 less than old size=$size1"
17103 }
17104 run_test 254 "Check changelog size"
17105
17106 ladvise_no_type()
17107 {
17108         local type=$1
17109         local file=$2
17110
17111         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17112                 awk -F: '{print $2}' | grep $type > /dev/null
17113         if [ $? -ne 0 ]; then
17114                 return 0
17115         fi
17116         return 1
17117 }
17118
17119 ladvise_no_ioctl()
17120 {
17121         local file=$1
17122
17123         lfs ladvise -a willread $file > /dev/null 2>&1
17124         if [ $? -eq 0 ]; then
17125                 return 1
17126         fi
17127
17128         lfs ladvise -a willread $file 2>&1 |
17129                 grep "Inappropriate ioctl for device" > /dev/null
17130         if [ $? -eq 0 ]; then
17131                 return 0
17132         fi
17133         return 1
17134 }
17135
17136 percent() {
17137         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17138 }
17139
17140 # run a random read IO workload
17141 # usage: random_read_iops <filename> <filesize> <iosize>
17142 random_read_iops() {
17143         local file=$1
17144         local fsize=$2
17145         local iosize=${3:-4096}
17146
17147         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17148                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17149 }
17150
17151 drop_file_oss_cache() {
17152         local file="$1"
17153         local nodes="$2"
17154
17155         $LFS ladvise -a dontneed $file 2>/dev/null ||
17156                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17157 }
17158
17159 ladvise_willread_performance()
17160 {
17161         local repeat=10
17162         local average_origin=0
17163         local average_cache=0
17164         local average_ladvise=0
17165
17166         for ((i = 1; i <= $repeat; i++)); do
17167                 echo "Iter $i/$repeat: reading without willread hint"
17168                 cancel_lru_locks osc
17169                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17170                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17171                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17172                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17173
17174                 cancel_lru_locks osc
17175                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17176                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17177                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17178
17179                 cancel_lru_locks osc
17180                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17181                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17182                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17183                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17184                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17185         done
17186         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17187         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17188         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17189
17190         speedup_cache=$(percent $average_cache $average_origin)
17191         speedup_ladvise=$(percent $average_ladvise $average_origin)
17192
17193         echo "Average uncached read: $average_origin"
17194         echo "Average speedup with OSS cached read: " \
17195                 "$average_cache = +$speedup_cache%"
17196         echo "Average speedup with ladvise willread: " \
17197                 "$average_ladvise = +$speedup_ladvise%"
17198
17199         local lowest_speedup=20
17200         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17201                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17202                         "got $average_cache%. Skipping ladvise willread check."
17203                 return 0
17204         fi
17205
17206         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17207         # it is still good to run until then to exercise 'ladvise willread'
17208         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17209                 [ "$ost1_FSTYPE" = "zfs" ] &&
17210                 echo "osd-zfs does not support dontneed or drop_caches" &&
17211                 return 0
17212
17213         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17214         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17215                 error_not_in_vm "Speedup with willread is less than " \
17216                         "$lowest_speedup%, got $average_ladvise%"
17217 }
17218
17219 test_255a() {
17220         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17221                 skip "lustre < 2.8.54 does not support ladvise "
17222         remote_ost_nodsh && skip "remote OST with nodsh"
17223
17224         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17225
17226         ladvise_no_type willread $DIR/$tfile &&
17227                 skip "willread ladvise is not supported"
17228
17229         ladvise_no_ioctl $DIR/$tfile &&
17230                 skip "ladvise ioctl is not supported"
17231
17232         local size_mb=100
17233         local size=$((size_mb * 1048576))
17234         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17235                 error "dd to $DIR/$tfile failed"
17236
17237         lfs ladvise -a willread $DIR/$tfile ||
17238                 error "Ladvise failed with no range argument"
17239
17240         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17241                 error "Ladvise failed with no -l or -e argument"
17242
17243         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17244                 error "Ladvise failed with only -e argument"
17245
17246         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17247                 error "Ladvise failed with only -l argument"
17248
17249         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17250                 error "End offset should not be smaller than start offset"
17251
17252         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17253                 error "End offset should not be equal to start offset"
17254
17255         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17256                 error "Ladvise failed with overflowing -s argument"
17257
17258         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17259                 error "Ladvise failed with overflowing -e argument"
17260
17261         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17262                 error "Ladvise failed with overflowing -l argument"
17263
17264         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17265                 error "Ladvise succeeded with conflicting -l and -e arguments"
17266
17267         echo "Synchronous ladvise should wait"
17268         local delay=4
17269 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17270         do_nodes $(comma_list $(osts_nodes)) \
17271                 $LCTL set_param fail_val=$delay fail_loc=0x237
17272
17273         local start_ts=$SECONDS
17274         lfs ladvise -a willread $DIR/$tfile ||
17275                 error "Ladvise failed with no range argument"
17276         local end_ts=$SECONDS
17277         local inteval_ts=$((end_ts - start_ts))
17278
17279         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17280                 error "Synchronous advice didn't wait reply"
17281         fi
17282
17283         echo "Asynchronous ladvise shouldn't wait"
17284         local start_ts=$SECONDS
17285         lfs ladvise -a willread -b $DIR/$tfile ||
17286                 error "Ladvise failed with no range argument"
17287         local end_ts=$SECONDS
17288         local inteval_ts=$((end_ts - start_ts))
17289
17290         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17291                 error "Asynchronous advice blocked"
17292         fi
17293
17294         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17295         ladvise_willread_performance
17296 }
17297 run_test 255a "check 'lfs ladvise -a willread'"
17298
17299 facet_meminfo() {
17300         local facet=$1
17301         local info=$2
17302
17303         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17304 }
17305
17306 test_255b() {
17307         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17308                 skip "lustre < 2.8.54 does not support ladvise "
17309         remote_ost_nodsh && skip "remote OST with nodsh"
17310
17311         lfs setstripe -c 1 -i 0 $DIR/$tfile
17312
17313         ladvise_no_type dontneed $DIR/$tfile &&
17314                 skip "dontneed ladvise is not supported"
17315
17316         ladvise_no_ioctl $DIR/$tfile &&
17317                 skip "ladvise ioctl is not supported"
17318
17319         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17320                 [ "$ost1_FSTYPE" = "zfs" ] &&
17321                 skip "zfs-osd does not support 'ladvise dontneed'"
17322
17323         local size_mb=100
17324         local size=$((size_mb * 1048576))
17325         # In order to prevent disturbance of other processes, only check 3/4
17326         # of the memory usage
17327         local kibibytes=$((size_mb * 1024 * 3 / 4))
17328
17329         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17330                 error "dd to $DIR/$tfile failed"
17331
17332         #force write to complete before dropping OST cache & checking memory
17333         sync
17334
17335         local total=$(facet_meminfo ost1 MemTotal)
17336         echo "Total memory: $total KiB"
17337
17338         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17339         local before_read=$(facet_meminfo ost1 Cached)
17340         echo "Cache used before read: $before_read KiB"
17341
17342         lfs ladvise -a willread $DIR/$tfile ||
17343                 error "Ladvise willread failed"
17344         local after_read=$(facet_meminfo ost1 Cached)
17345         echo "Cache used after read: $after_read KiB"
17346
17347         lfs ladvise -a dontneed $DIR/$tfile ||
17348                 error "Ladvise dontneed again failed"
17349         local no_read=$(facet_meminfo ost1 Cached)
17350         echo "Cache used after dontneed ladvise: $no_read KiB"
17351
17352         if [ $total -lt $((before_read + kibibytes)) ]; then
17353                 echo "Memory is too small, abort checking"
17354                 return 0
17355         fi
17356
17357         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17358                 error "Ladvise willread should use more memory" \
17359                         "than $kibibytes KiB"
17360         fi
17361
17362         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17363                 error "Ladvise dontneed should release more memory" \
17364                         "than $kibibytes KiB"
17365         fi
17366 }
17367 run_test 255b "check 'lfs ladvise -a dontneed'"
17368
17369 test_255c() {
17370         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17371                 skip "lustre < 2.10.53 does not support lockahead"
17372
17373         local count
17374         local new_count
17375         local difference
17376         local i
17377         local rc
17378
17379         test_mkdir -p $DIR/$tdir
17380         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17381
17382         #test 10 returns only success/failure
17383         i=10
17384         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17385         rc=$?
17386         if [ $rc -eq 255 ]; then
17387                 error "Ladvise test${i} failed, ${rc}"
17388         fi
17389
17390         #test 11 counts lock enqueue requests, all others count new locks
17391         i=11
17392         count=$(do_facet ost1 \
17393                 $LCTL get_param -n ost.OSS.ost.stats)
17394         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17395
17396         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17397         rc=$?
17398         if [ $rc -eq 255 ]; then
17399                 error "Ladvise test${i} failed, ${rc}"
17400         fi
17401
17402         new_count=$(do_facet ost1 \
17403                 $LCTL get_param -n ost.OSS.ost.stats)
17404         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17405                    awk '{ print $2 }')
17406
17407         difference="$((new_count - count))"
17408         if [ $difference -ne $rc ]; then
17409                 error "Ladvise test${i}, bad enqueue count, returned " \
17410                       "${rc}, actual ${difference}"
17411         fi
17412
17413         for i in $(seq 12 21); do
17414                 # If we do not do this, we run the risk of having too many
17415                 # locks and starting lock cancellation while we are checking
17416                 # lock counts.
17417                 cancel_lru_locks osc
17418
17419                 count=$($LCTL get_param -n \
17420                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17421
17422                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17423                 rc=$?
17424                 if [ $rc -eq 255 ]; then
17425                         error "Ladvise test ${i} failed, ${rc}"
17426                 fi
17427
17428                 new_count=$($LCTL get_param -n \
17429                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17430                 difference="$((new_count - count))"
17431
17432                 # Test 15 output is divided by 100 to map down to valid return
17433                 if [ $i -eq 15 ]; then
17434                         rc="$((rc * 100))"
17435                 fi
17436
17437                 if [ $difference -ne $rc ]; then
17438                         error "Ladvise test ${i}, bad lock count, returned " \
17439                               "${rc}, actual ${difference}"
17440                 fi
17441         done
17442
17443         #test 22 returns only success/failure
17444         i=22
17445         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17446         rc=$?
17447         if [ $rc -eq 255 ]; then
17448                 error "Ladvise test${i} failed, ${rc}"
17449         fi
17450 }
17451 run_test 255c "suite of ladvise lockahead tests"
17452
17453 test_256() {
17454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17455         remote_mds_nodsh && skip "remote MDS with nodsh"
17456         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17457         changelog_users $SINGLEMDS | grep "^cl" &&
17458                 skip "active changelog user"
17459
17460         local cl_user
17461         local cat_sl
17462         local mdt_dev
17463
17464         mdt_dev=$(mdsdevname 1)
17465         echo $mdt_dev
17466
17467         changelog_register || error "changelog_register failed"
17468
17469         rm -rf $DIR/$tdir
17470         mkdir -p $DIR/$tdir
17471
17472         changelog_clear 0 || error "changelog_clear failed"
17473
17474         # change something
17475         touch $DIR/$tdir/{1..10}
17476
17477         # stop the MDT
17478         stop $SINGLEMDS || error "Fail to stop MDT"
17479
17480         # remount the MDT
17481
17482         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17483
17484         #after mount new plainllog is used
17485         touch $DIR/$tdir/{11..19}
17486         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17487         cat_sl=$(do_facet $SINGLEMDS "sync; \
17488                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17489                  llog_reader $tmpfile | grep -c type=1064553b")
17490         do_facet $SINGLEMDS llog_reader $tmpfile
17491
17492         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17493
17494         changelog_clear 0 || error "changelog_clear failed"
17495
17496         cat_sl=$(do_facet $SINGLEMDS "sync; \
17497                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17498                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17499
17500         if (( cat_sl == 2 )); then
17501                 error "Empty plain llog was not deleted from changelog catalog"
17502         elif (( cat_sl != 1 )); then
17503                 error "Active plain llog shouldn't be deleted from catalog"
17504         fi
17505 }
17506 run_test 256 "Check llog delete for empty and not full state"
17507
17508 test_257() {
17509         remote_mds_nodsh && skip "remote MDS with nodsh"
17510         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17511                 skip "Need MDS version at least 2.8.55"
17512
17513         test_mkdir $DIR/$tdir
17514
17515         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17516                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17517         stat $DIR/$tdir
17518
17519 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17520         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17521         local facet=mds$((mdtidx + 1))
17522         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17523         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17524
17525         stop $facet || error "stop MDS failed"
17526         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17527                 error "start MDS fail"
17528         wait_recovery_complete $facet
17529 }
17530 run_test 257 "xattr locks are not lost"
17531
17532 # Verify we take the i_mutex when security requires it
17533 test_258a() {
17534 #define OBD_FAIL_IMUTEX_SEC 0x141c
17535         $LCTL set_param fail_loc=0x141c
17536         touch $DIR/$tfile
17537         chmod u+s $DIR/$tfile
17538         chmod a+rwx $DIR/$tfile
17539         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17540         RC=$?
17541         if [ $RC -ne 0 ]; then
17542                 error "error, failed to take i_mutex, rc=$?"
17543         fi
17544         rm -f $DIR/$tfile
17545 }
17546 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17547
17548 # Verify we do NOT take the i_mutex in the normal case
17549 test_258b() {
17550 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17551         $LCTL set_param fail_loc=0x141d
17552         touch $DIR/$tfile
17553         chmod a+rwx $DIR
17554         chmod a+rw $DIR/$tfile
17555         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17556         RC=$?
17557         if [ $RC -ne 0 ]; then
17558                 error "error, took i_mutex unnecessarily, rc=$?"
17559         fi
17560         rm -f $DIR/$tfile
17561
17562 }
17563 run_test 258b "verify i_mutex security behavior"
17564
17565 test_259() {
17566         local file=$DIR/$tfile
17567         local before
17568         local after
17569
17570         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17571
17572         stack_trap "rm -f $file" EXIT
17573
17574         wait_delete_completed
17575         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17576         echo "before: $before"
17577
17578         $LFS setstripe -i 0 -c 1 $file
17579         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17580         sync_all_data
17581         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17582         echo "after write: $after"
17583
17584 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17585         do_facet ost1 $LCTL set_param fail_loc=0x2301
17586         $TRUNCATE $file 0
17587         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17588         echo "after truncate: $after"
17589
17590         stop ost1
17591         do_facet ost1 $LCTL set_param fail_loc=0
17592         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17593         sleep 2
17594         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17595         echo "after restart: $after"
17596         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17597                 error "missing truncate?"
17598
17599         return 0
17600 }
17601 run_test 259 "crash at delayed truncate"
17602
17603 test_260() {
17604 #define OBD_FAIL_MDC_CLOSE               0x806
17605         $LCTL set_param fail_loc=0x80000806
17606         touch $DIR/$tfile
17607
17608 }
17609 run_test 260 "Check mdc_close fail"
17610
17611 ### Data-on-MDT sanity tests ###
17612 test_270a() {
17613         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17614                 skip "Need MDS version at least 2.10.55 for DoM"
17615
17616         # create DoM file
17617         local dom=$DIR/$tdir/dom_file
17618         local tmp=$DIR/$tdir/tmp_file
17619
17620         mkdir -p $DIR/$tdir
17621
17622         # basic checks for DoM component creation
17623         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17624                 error "Can set MDT layout to non-first entry"
17625
17626         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17627                 error "Can define multiple entries as MDT layout"
17628
17629         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17630
17631         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17632         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17633         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17634
17635         local mdtidx=$($LFS getstripe -m $dom)
17636         local mdtname=MDT$(printf %04x $mdtidx)
17637         local facet=mds$((mdtidx + 1))
17638         local space_check=1
17639
17640         # Skip free space checks with ZFS
17641         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17642
17643         # write
17644         sync
17645         local size_tmp=$((65536 * 3))
17646         local mdtfree1=$(do_facet $facet \
17647                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17648
17649         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17650         # check also direct IO along write
17651         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17652         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17653         sync
17654         cmp $tmp $dom || error "file data is different"
17655         [ $(stat -c%s $dom) == $size_tmp ] ||
17656                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17657         if [ $space_check == 1 ]; then
17658                 local mdtfree2=$(do_facet $facet \
17659                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17660
17661                 # increase in usage from by $size_tmp
17662                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17663                         error "MDT free space wrong after write: " \
17664                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17665         fi
17666
17667         # truncate
17668         local size_dom=10000
17669
17670         $TRUNCATE $dom $size_dom
17671         [ $(stat -c%s $dom) == $size_dom ] ||
17672                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17673         if [ $space_check == 1 ]; then
17674                 mdtfree1=$(do_facet $facet \
17675                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17676                 # decrease in usage from $size_tmp to new $size_dom
17677                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17678                   $(((size_tmp - size_dom) / 1024)) ] ||
17679                         error "MDT free space is wrong after truncate: " \
17680                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17681         fi
17682
17683         # append
17684         cat $tmp >> $dom
17685         sync
17686         size_dom=$((size_dom + size_tmp))
17687         [ $(stat -c%s $dom) == $size_dom ] ||
17688                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17689         if [ $space_check == 1 ]; then
17690                 mdtfree2=$(do_facet $facet \
17691                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17692                 # increase in usage by $size_tmp from previous
17693                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17694                         error "MDT free space is wrong after append: " \
17695                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17696         fi
17697
17698         # delete
17699         rm $dom
17700         if [ $space_check == 1 ]; then
17701                 mdtfree1=$(do_facet $facet \
17702                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17703                 # decrease in usage by $size_dom from previous
17704                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17705                         error "MDT free space is wrong after removal: " \
17706                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17707         fi
17708
17709         # combined striping
17710         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17711                 error "Can't create DoM + OST striping"
17712
17713         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17714         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17715         # check also direct IO along write
17716         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17717         sync
17718         cmp $tmp $dom || error "file data is different"
17719         [ $(stat -c%s $dom) == $size_tmp ] ||
17720                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17721         rm $dom $tmp
17722
17723         return 0
17724 }
17725 run_test 270a "DoM: basic functionality tests"
17726
17727 test_270b() {
17728         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17729                 skip "Need MDS version at least 2.10.55"
17730
17731         local dom=$DIR/$tdir/dom_file
17732         local max_size=1048576
17733
17734         mkdir -p $DIR/$tdir
17735         $LFS setstripe -E $max_size -L mdt $dom
17736
17737         # truncate over the limit
17738         $TRUNCATE $dom $(($max_size + 1)) &&
17739                 error "successful truncate over the maximum size"
17740         # write over the limit
17741         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17742                 error "successful write over the maximum size"
17743         # append over the limit
17744         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17745         echo "12345" >> $dom && error "successful append over the maximum size"
17746         rm $dom
17747
17748         return 0
17749 }
17750 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17751
17752 test_270c() {
17753         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17754                 skip "Need MDS version at least 2.10.55"
17755
17756         mkdir -p $DIR/$tdir
17757         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17758
17759         # check files inherit DoM EA
17760         touch $DIR/$tdir/first
17761         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17762                 error "bad pattern"
17763         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17764                 error "bad stripe count"
17765         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17766                 error "bad stripe size"
17767
17768         # check directory inherits DoM EA and uses it as default
17769         mkdir $DIR/$tdir/subdir
17770         touch $DIR/$tdir/subdir/second
17771         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17772                 error "bad pattern in sub-directory"
17773         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17774                 error "bad stripe count in sub-directory"
17775         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17776                 error "bad stripe size in sub-directory"
17777         return 0
17778 }
17779 run_test 270c "DoM: DoM EA inheritance tests"
17780
17781 test_270d() {
17782         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17783                 skip "Need MDS version at least 2.10.55"
17784
17785         mkdir -p $DIR/$tdir
17786         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17787
17788         # inherit default DoM striping
17789         mkdir $DIR/$tdir/subdir
17790         touch $DIR/$tdir/subdir/f1
17791
17792         # change default directory striping
17793         $LFS setstripe -c 1 $DIR/$tdir/subdir
17794         touch $DIR/$tdir/subdir/f2
17795         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17796                 error "wrong default striping in file 2"
17797         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17798                 error "bad pattern in file 2"
17799         return 0
17800 }
17801 run_test 270d "DoM: change striping from DoM to RAID0"
17802
17803 test_270e() {
17804         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17805                 skip "Need MDS version at least 2.10.55"
17806
17807         mkdir -p $DIR/$tdir/dom
17808         mkdir -p $DIR/$tdir/norm
17809         DOMFILES=20
17810         NORMFILES=10
17811         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17812         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17813
17814         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17815         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17816
17817         # find DoM files by layout
17818         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17819         [ $NUM -eq  $DOMFILES ] ||
17820                 error "lfs find -L: found $NUM, expected $DOMFILES"
17821         echo "Test 1: lfs find 20 DOM files by layout: OK"
17822
17823         # there should be 1 dir with default DOM striping
17824         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17825         [ $NUM -eq  1 ] ||
17826                 error "lfs find -L: found $NUM, expected 1 dir"
17827         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17828
17829         # find DoM files by stripe size
17830         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17831         [ $NUM -eq  $DOMFILES ] ||
17832                 error "lfs find -S: found $NUM, expected $DOMFILES"
17833         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17834
17835         # find files by stripe offset except DoM files
17836         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17837         [ $NUM -eq  $NORMFILES ] ||
17838                 error "lfs find -i: found $NUM, expected $NORMFILES"
17839         echo "Test 5: lfs find no DOM files by stripe index: OK"
17840         return 0
17841 }
17842 run_test 270e "DoM: lfs find with DoM files test"
17843
17844 test_270f() {
17845         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17846                 skip "Need MDS version at least 2.10.55"
17847
17848         local mdtname=${FSNAME}-MDT0000-mdtlov
17849         local dom=$DIR/$tdir/dom_file
17850         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17851                                                 lod.$mdtname.dom_stripesize)
17852         local dom_limit=131072
17853
17854         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17855         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17856                                                 lod.$mdtname.dom_stripesize)
17857         [ ${dom_limit} -eq ${dom_current} ] ||
17858                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17859
17860         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17861         $LFS setstripe -d $DIR/$tdir
17862         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17863                 error "Can't set directory default striping"
17864
17865         # exceed maximum stripe size
17866         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17867                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17868         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17869                 error "Able to create DoM component size more than LOD limit"
17870
17871         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17872         dom_current=$(do_facet mds1 $LCTL get_param -n \
17873                                                 lod.$mdtname.dom_stripesize)
17874         [ 0 -eq ${dom_current} ] ||
17875                 error "Can't set zero DoM stripe limit"
17876         rm $dom
17877
17878         # attempt to create DoM file on server with disabled DoM should
17879         # remove DoM entry from layout and be succeed
17880         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17881                 error "Can't create DoM file (DoM is disabled)"
17882         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17883                 error "File has DoM component while DoM is disabled"
17884         rm $dom
17885
17886         # attempt to create DoM file with only DoM stripe should return error
17887         $LFS setstripe -E $dom_limit -L mdt $dom &&
17888                 error "Able to create DoM-only file while DoM is disabled"
17889
17890         # too low values to be aligned with smallest stripe size 64K
17891         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17892         dom_current=$(do_facet mds1 $LCTL get_param -n \
17893                                                 lod.$mdtname.dom_stripesize)
17894         [ 30000 -eq ${dom_current} ] &&
17895                 error "Can set too small DoM stripe limit"
17896
17897         # 64K is a minimal stripe size in Lustre, expect limit of that size
17898         [ 65536 -eq ${dom_current} ] ||
17899                 error "Limit is not set to 64K but ${dom_current}"
17900
17901         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17902         dom_current=$(do_facet mds1 $LCTL get_param -n \
17903                                                 lod.$mdtname.dom_stripesize)
17904         echo $dom_current
17905         [ 2147483648 -eq ${dom_current} ] &&
17906                 error "Can set too large DoM stripe limit"
17907
17908         do_facet mds1 $LCTL set_param -n \
17909                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17910         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17911                 error "Can't create DoM component size after limit change"
17912         do_facet mds1 $LCTL set_param -n \
17913                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17914         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17915                 error "Can't create DoM file after limit decrease"
17916         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17917                 error "Can create big DoM component after limit decrease"
17918         touch ${dom}_def ||
17919                 error "Can't create file with old default layout"
17920
17921         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17922         return 0
17923 }
17924 run_test 270f "DoM: maximum DoM stripe size checks"
17925
17926 test_271a() {
17927         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17928                 skip "Need MDS version at least 2.10.55"
17929
17930         local dom=$DIR/$tdir/dom
17931
17932         mkdir -p $DIR/$tdir
17933
17934         $LFS setstripe -E 1024K -L mdt $dom
17935
17936         lctl set_param -n mdc.*.stats=clear
17937         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17938         cat $dom > /dev/null
17939         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17940         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17941         ls $dom
17942         rm -f $dom
17943 }
17944 run_test 271a "DoM: data is cached for read after write"
17945
17946 test_271b() {
17947         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17948                 skip "Need MDS version at least 2.10.55"
17949
17950         local dom=$DIR/$tdir/dom
17951
17952         mkdir -p $DIR/$tdir
17953
17954         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17955
17956         lctl set_param -n mdc.*.stats=clear
17957         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17958         cancel_lru_locks mdc
17959         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17960         # second stat to check size is cached on client
17961         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17962         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17963         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17964         rm -f $dom
17965 }
17966 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17967
17968 test_271ba() {
17969         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17970                 skip "Need MDS version at least 2.10.55"
17971
17972         local dom=$DIR/$tdir/dom
17973
17974         mkdir -p $DIR/$tdir
17975
17976         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17977
17978         lctl set_param -n mdc.*.stats=clear
17979         lctl set_param -n osc.*.stats=clear
17980         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17981         cancel_lru_locks mdc
17982         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17983         # second stat to check size is cached on client
17984         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17985         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17986         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17987         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17988         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17989         rm -f $dom
17990 }
17991 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17992
17993
17994 get_mdc_stats() {
17995         local mdtidx=$1
17996         local param=$2
17997         local mdt=MDT$(printf %04x $mdtidx)
17998
17999         if [ -z $param ]; then
18000                 lctl get_param -n mdc.*$mdt*.stats
18001         else
18002                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18003         fi
18004 }
18005
18006 test_271c() {
18007         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18008                 skip "Need MDS version at least 2.10.55"
18009
18010         local dom=$DIR/$tdir/dom
18011
18012         mkdir -p $DIR/$tdir
18013
18014         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18015
18016         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18017         local facet=mds$((mdtidx + 1))
18018
18019         cancel_lru_locks mdc
18020         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18021         createmany -o $dom 1000
18022         lctl set_param -n mdc.*.stats=clear
18023         smalliomany -w $dom 1000 200
18024         get_mdc_stats $mdtidx
18025         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18026         # Each file has 1 open, 1 IO enqueues, total 2000
18027         # but now we have also +1 getxattr for security.capability, total 3000
18028         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18029         unlinkmany $dom 1000
18030
18031         cancel_lru_locks mdc
18032         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18033         createmany -o $dom 1000
18034         lctl set_param -n mdc.*.stats=clear
18035         smalliomany -w $dom 1000 200
18036         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18037         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18038         # for OPEN and IO lock.
18039         [ $((enq - enq_2)) -ge 1000 ] ||
18040                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18041         unlinkmany $dom 1000
18042         return 0
18043 }
18044 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18045
18046 cleanup_271def_tests() {
18047         trap 0
18048         rm -f $1
18049 }
18050
18051 test_271d() {
18052         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18053                 skip "Need MDS version at least 2.10.57"
18054
18055         local dom=$DIR/$tdir/dom
18056         local tmp=$TMP/$tfile
18057         trap "cleanup_271def_tests $tmp" EXIT
18058
18059         mkdir -p $DIR/$tdir
18060
18061         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18062
18063         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18064
18065         cancel_lru_locks mdc
18066         dd if=/dev/urandom of=$tmp bs=1000 count=1
18067         dd if=$tmp of=$dom bs=1000 count=1
18068         cancel_lru_locks mdc
18069
18070         cat /etc/hosts >> $tmp
18071         lctl set_param -n mdc.*.stats=clear
18072
18073         # append data to the same file it should update local page
18074         echo "Append to the same page"
18075         cat /etc/hosts >> $dom
18076         local num=$(get_mdc_stats $mdtidx ost_read)
18077         local ra=$(get_mdc_stats $mdtidx req_active)
18078         local rw=$(get_mdc_stats $mdtidx req_waittime)
18079
18080         [ -z $num ] || error "$num READ RPC occured"
18081         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18082         echo "... DONE"
18083
18084         # compare content
18085         cmp $tmp $dom || error "file miscompare"
18086
18087         cancel_lru_locks mdc
18088         lctl set_param -n mdc.*.stats=clear
18089
18090         echo "Open and read file"
18091         cat $dom > /dev/null
18092         local num=$(get_mdc_stats $mdtidx ost_read)
18093         local ra=$(get_mdc_stats $mdtidx req_active)
18094         local rw=$(get_mdc_stats $mdtidx req_waittime)
18095
18096         [ -z $num ] || error "$num READ RPC occured"
18097         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18098         echo "... DONE"
18099
18100         # compare content
18101         cmp $tmp $dom || error "file miscompare"
18102
18103         return 0
18104 }
18105 run_test 271d "DoM: read on open (1K file in reply buffer)"
18106
18107 test_271f() {
18108         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18109                 skip "Need MDS version at least 2.10.57"
18110
18111         local dom=$DIR/$tdir/dom
18112         local tmp=$TMP/$tfile
18113         trap "cleanup_271def_tests $tmp" EXIT
18114
18115         mkdir -p $DIR/$tdir
18116
18117         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18118
18119         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18120
18121         cancel_lru_locks mdc
18122         dd if=/dev/urandom of=$tmp bs=200000 count=1
18123         dd if=$tmp of=$dom bs=200000 count=1
18124         cancel_lru_locks mdc
18125         cat /etc/hosts >> $tmp
18126         lctl set_param -n mdc.*.stats=clear
18127
18128         echo "Append to the same page"
18129         cat /etc/hosts >> $dom
18130         local num=$(get_mdc_stats $mdtidx ost_read)
18131         local ra=$(get_mdc_stats $mdtidx req_active)
18132         local rw=$(get_mdc_stats $mdtidx req_waittime)
18133
18134         [ -z $num ] || error "$num READ RPC occured"
18135         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18136         echo "... DONE"
18137
18138         # compare content
18139         cmp $tmp $dom || error "file miscompare"
18140
18141         cancel_lru_locks mdc
18142         lctl set_param -n mdc.*.stats=clear
18143
18144         echo "Open and read file"
18145         cat $dom > /dev/null
18146         local num=$(get_mdc_stats $mdtidx ost_read)
18147         local ra=$(get_mdc_stats $mdtidx req_active)
18148         local rw=$(get_mdc_stats $mdtidx req_waittime)
18149
18150         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18151         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18152         echo "... DONE"
18153
18154         # compare content
18155         cmp $tmp $dom || error "file miscompare"
18156
18157         return 0
18158 }
18159 run_test 271f "DoM: read on open (200K file and read tail)"
18160
18161 test_271g() {
18162         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18163                 skip "Skipping due to old client or server version"
18164
18165         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18166         # to get layout
18167         $CHECKSTAT -t file $DIR1/$tfile
18168
18169         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18170         MULTIOP_PID=$!
18171         sleep 1
18172         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18173         $LCTL set_param fail_loc=0x80000314
18174         rm $DIR1/$tfile || error "Unlink fails"
18175         RC=$?
18176         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18177         [ $RC -eq 0 ] || error "Failed write to stale object"
18178 }
18179 run_test 271g "Discard DoM data vs client flush race"
18180
18181 test_272a() {
18182         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18183                 skip "Need MDS version at least 2.11.50"
18184
18185         local dom=$DIR/$tdir/dom
18186         mkdir -p $DIR/$tdir
18187
18188         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18189         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18190                 error "failed to write data into $dom"
18191         local old_md5=$(md5sum $dom)
18192
18193         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18194                 error "failed to migrate to the same DoM component"
18195
18196         local new_md5=$(md5sum $dom)
18197
18198         [ "$old_md5" == "$new_md5" ] ||
18199                 error "md5sum differ: $old_md5, $new_md5"
18200
18201         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18202                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18203 }
18204 run_test 272a "DoM migration: new layout with the same DOM component"
18205
18206 test_272b() {
18207         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18208                 skip "Need MDS version at least 2.11.50"
18209
18210         local dom=$DIR/$tdir/dom
18211         mkdir -p $DIR/$tdir
18212         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18213
18214         local mdtidx=$($LFS getstripe -m $dom)
18215         local mdtname=MDT$(printf %04x $mdtidx)
18216         local facet=mds$((mdtidx + 1))
18217
18218         local mdtfree1=$(do_facet $facet \
18219                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18220         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18221                 error "failed to write data into $dom"
18222         local old_md5=$(md5sum $dom)
18223         cancel_lru_locks mdc
18224         local mdtfree1=$(do_facet $facet \
18225                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18226
18227         $LFS migrate -c2 $dom ||
18228                 error "failed to migrate to the new composite layout"
18229         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18230                 error "MDT stripe was not removed"
18231
18232         cancel_lru_locks mdc
18233         local new_md5=$(md5sum $dom)
18234         [ "$old_md5" != "$new_md5" ] &&
18235                 error "$old_md5 != $new_md5"
18236
18237         # Skip free space checks with ZFS
18238         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18239                 local mdtfree2=$(do_facet $facet \
18240                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18241                 [ $mdtfree2 -gt $mdtfree1 ] ||
18242                         error "MDT space is not freed after migration"
18243         fi
18244         return 0
18245 }
18246 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18247
18248 test_272c() {
18249         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18250                 skip "Need MDS version at least 2.11.50"
18251
18252         local dom=$DIR/$tdir/$tfile
18253         mkdir -p $DIR/$tdir
18254         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18255
18256         local mdtidx=$($LFS getstripe -m $dom)
18257         local mdtname=MDT$(printf %04x $mdtidx)
18258         local facet=mds$((mdtidx + 1))
18259
18260         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18261                 error "failed to write data into $dom"
18262         local old_md5=$(md5sum $dom)
18263         cancel_lru_locks mdc
18264         local mdtfree1=$(do_facet $facet \
18265                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18266
18267         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18268                 error "failed to migrate to the new composite layout"
18269         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18270                 error "MDT stripe was not removed"
18271
18272         cancel_lru_locks mdc
18273         local new_md5=$(md5sum $dom)
18274         [ "$old_md5" != "$new_md5" ] &&
18275                 error "$old_md5 != $new_md5"
18276
18277         # Skip free space checks with ZFS
18278         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18279                 local mdtfree2=$(do_facet $facet \
18280                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18281                 [ $mdtfree2 -gt $mdtfree1 ] ||
18282                         error "MDS space is not freed after migration"
18283         fi
18284         return 0
18285 }
18286 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18287
18288 test_273a() {
18289         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18290                 skip "Need MDS version at least 2.11.50"
18291
18292         # Layout swap cannot be done if either file has DOM component,
18293         # this will never be supported, migration should be used instead
18294
18295         local dom=$DIR/$tdir/$tfile
18296         mkdir -p $DIR/$tdir
18297
18298         $LFS setstripe -c2 ${dom}_plain
18299         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18300         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18301                 error "can swap layout with DoM component"
18302         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18303                 error "can swap layout with DoM component"
18304
18305         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18306         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18307                 error "can swap layout with DoM component"
18308         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18309                 error "can swap layout with DoM component"
18310         return 0
18311 }
18312 run_test 273a "DoM: layout swapping should fail with DOM"
18313
18314 test_275() {
18315         remote_ost_nodsh && skip "remote OST with nodsh"
18316         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18317                 skip "Need OST version >= 2.10.57"
18318
18319         local file=$DIR/$tfile
18320         local oss
18321
18322         oss=$(comma_list $(osts_nodes))
18323
18324         dd if=/dev/urandom of=$file bs=1M count=2 ||
18325                 error "failed to create a file"
18326         cancel_lru_locks osc
18327
18328         #lock 1
18329         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18330                 error "failed to read a file"
18331
18332 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18333         $LCTL set_param fail_loc=0x8000031f
18334
18335         cancel_lru_locks osc &
18336         sleep 1
18337
18338 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18339         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18340         #IO takes another lock, but matches the PENDING one
18341         #and places it to the IO RPC
18342         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18343                 error "failed to read a file with PENDING lock"
18344 }
18345 run_test 275 "Read on a canceled duplicate lock"
18346
18347 test_276() {
18348         remote_ost_nodsh && skip "remote OST with nodsh"
18349         local pid
18350
18351         do_facet ost1 "(while true; do \
18352                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18353                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18354         pid=$!
18355
18356         for LOOP in $(seq 20); do
18357                 stop ost1
18358                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18359         done
18360         kill -9 $pid
18361         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18362                 rm $TMP/sanity_276_pid"
18363 }
18364 run_test 276 "Race between mount and obd_statfs"
18365
18366 test_277() {
18367         $LCTL set_param ldlm.namespaces.*.lru_size=0
18368         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
18369         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18370                         grep ^used_mb | awk '{print $2}')
18371         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
18372         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
18373                 oflag=direct conv=notrunc
18374         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18375                         grep ^used_mb | awk '{print $2}')
18376         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
18377 }
18378 run_test 277 "Direct IO shall drop page cache"
18379
18380 cleanup_test_300() {
18381         trap 0
18382         umask $SAVE_UMASK
18383 }
18384 test_striped_dir() {
18385         local mdt_index=$1
18386         local stripe_count
18387         local stripe_index
18388
18389         mkdir -p $DIR/$tdir
18390
18391         SAVE_UMASK=$(umask)
18392         trap cleanup_test_300 RETURN EXIT
18393
18394         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18395                                                 $DIR/$tdir/striped_dir ||
18396                 error "set striped dir error"
18397
18398         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18399         [ "$mode" = "755" ] || error "expect 755 got $mode"
18400
18401         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18402                 error "getdirstripe failed"
18403         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18404         if [ "$stripe_count" != "2" ]; then
18405                 error "1:stripe_count is $stripe_count, expect 2"
18406         fi
18407         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18408         if [ "$stripe_count" != "2" ]; then
18409                 error "2:stripe_count is $stripe_count, expect 2"
18410         fi
18411
18412         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18413         if [ "$stripe_index" != "$mdt_index" ]; then
18414                 error "stripe_index is $stripe_index, expect $mdt_index"
18415         fi
18416
18417         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18418                 error "nlink error after create striped dir"
18419
18420         mkdir $DIR/$tdir/striped_dir/a
18421         mkdir $DIR/$tdir/striped_dir/b
18422
18423         stat $DIR/$tdir/striped_dir/a ||
18424                 error "create dir under striped dir failed"
18425         stat $DIR/$tdir/striped_dir/b ||
18426                 error "create dir under striped dir failed"
18427
18428         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18429                 error "nlink error after mkdir"
18430
18431         rmdir $DIR/$tdir/striped_dir/a
18432         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18433                 error "nlink error after rmdir"
18434
18435         rmdir $DIR/$tdir/striped_dir/b
18436         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18437                 error "nlink error after rmdir"
18438
18439         chattr +i $DIR/$tdir/striped_dir
18440         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18441                 error "immutable flags not working under striped dir!"
18442         chattr -i $DIR/$tdir/striped_dir
18443
18444         rmdir $DIR/$tdir/striped_dir ||
18445                 error "rmdir striped dir error"
18446
18447         cleanup_test_300
18448
18449         true
18450 }
18451
18452 test_300a() {
18453         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18454                 skip "skipped for lustre < 2.7.0"
18455         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18456         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18457
18458         test_striped_dir 0 || error "failed on striped dir on MDT0"
18459         test_striped_dir 1 || error "failed on striped dir on MDT0"
18460 }
18461 run_test 300a "basic striped dir sanity test"
18462
18463 test_300b() {
18464         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18465                 skip "skipped for lustre < 2.7.0"
18466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18467         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18468
18469         local i
18470         local mtime1
18471         local mtime2
18472         local mtime3
18473
18474         test_mkdir $DIR/$tdir || error "mkdir fail"
18475         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18476                 error "set striped dir error"
18477         for i in {0..9}; do
18478                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18479                 sleep 1
18480                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18481                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18482                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18483                 sleep 1
18484                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18485                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18486                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18487         done
18488         true
18489 }
18490 run_test 300b "check ctime/mtime for striped dir"
18491
18492 test_300c() {
18493         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18494                 skip "skipped for lustre < 2.7.0"
18495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18496         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18497
18498         local file_count
18499
18500         mkdir -p $DIR/$tdir
18501         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18502                 error "set striped dir error"
18503
18504         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18505                 error "chown striped dir failed"
18506
18507         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18508                 error "create 5k files failed"
18509
18510         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18511
18512         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18513
18514         rm -rf $DIR/$tdir
18515 }
18516 run_test 300c "chown && check ls under striped directory"
18517
18518 test_300d() {
18519         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18520                 skip "skipped for lustre < 2.7.0"
18521         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18522         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18523
18524         local stripe_count
18525         local file
18526
18527         mkdir -p $DIR/$tdir
18528         $LFS setstripe -c 2 $DIR/$tdir
18529
18530         #local striped directory
18531         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18532                 error "set striped dir error"
18533         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18534                 error "create 10 files failed"
18535
18536         #remote striped directory
18537         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18538                 error "set striped dir error"
18539         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18540                 error "create 10 files failed"
18541
18542         for file in $(find $DIR/$tdir); do
18543                 stripe_count=$($LFS getstripe -c $file)
18544                 [ $stripe_count -eq 2 ] ||
18545                         error "wrong stripe $stripe_count for $file"
18546         done
18547
18548         rm -rf $DIR/$tdir
18549 }
18550 run_test 300d "check default stripe under striped directory"
18551
18552 test_300e() {
18553         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18554                 skip "Need MDS version at least 2.7.55"
18555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18557
18558         local stripe_count
18559         local file
18560
18561         mkdir -p $DIR/$tdir
18562
18563         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18564                 error "set striped dir error"
18565
18566         touch $DIR/$tdir/striped_dir/a
18567         touch $DIR/$tdir/striped_dir/b
18568         touch $DIR/$tdir/striped_dir/c
18569
18570         mkdir $DIR/$tdir/striped_dir/dir_a
18571         mkdir $DIR/$tdir/striped_dir/dir_b
18572         mkdir $DIR/$tdir/striped_dir/dir_c
18573
18574         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18575                 error "set striped adir under striped dir error"
18576
18577         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18578                 error "set striped bdir under striped dir error"
18579
18580         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18581                 error "set striped cdir under striped dir error"
18582
18583         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18584                 error "rename dir under striped dir fails"
18585
18586         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18587                 error "rename dir under different stripes fails"
18588
18589         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18590                 error "rename file under striped dir should succeed"
18591
18592         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18593                 error "rename dir under striped dir should succeed"
18594
18595         rm -rf $DIR/$tdir
18596 }
18597 run_test 300e "check rename under striped directory"
18598
18599 test_300f() {
18600         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18601         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18602         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18603                 skip "Need MDS version at least 2.7.55"
18604
18605         local stripe_count
18606         local file
18607
18608         rm -rf $DIR/$tdir
18609         mkdir -p $DIR/$tdir
18610
18611         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18612                 error "set striped dir error"
18613
18614         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18615                 error "set striped dir error"
18616
18617         touch $DIR/$tdir/striped_dir/a
18618         mkdir $DIR/$tdir/striped_dir/dir_a
18619         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18620                 error "create striped dir under striped dir fails"
18621
18622         touch $DIR/$tdir/striped_dir1/b
18623         mkdir $DIR/$tdir/striped_dir1/dir_b
18624         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18625                 error "create striped dir under striped dir fails"
18626
18627         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18628                 error "rename dir under different striped dir should fail"
18629
18630         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18631                 error "rename striped dir under diff striped dir should fail"
18632
18633         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18634                 error "rename file under diff striped dirs fails"
18635
18636         rm -rf $DIR/$tdir
18637 }
18638 run_test 300f "check rename cross striped directory"
18639
18640 test_300_check_default_striped_dir()
18641 {
18642         local dirname=$1
18643         local default_count=$2
18644         local default_index=$3
18645         local stripe_count
18646         local stripe_index
18647         local dir_stripe_index
18648         local dir
18649
18650         echo "checking $dirname $default_count $default_index"
18651         $LFS setdirstripe -D -c $default_count -i $default_index \
18652                                 -t all_char $DIR/$tdir/$dirname ||
18653                 error "set default stripe on striped dir error"
18654         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18655         [ $stripe_count -eq $default_count ] ||
18656                 error "expect $default_count get $stripe_count for $dirname"
18657
18658         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18659         [ $stripe_index -eq $default_index ] ||
18660                 error "expect $default_index get $stripe_index for $dirname"
18661
18662         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18663                                                 error "create dirs failed"
18664
18665         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18666         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18667         for dir in $(find $DIR/$tdir/$dirname/*); do
18668                 stripe_count=$($LFS getdirstripe -c $dir)
18669                 [ $stripe_count -eq $default_count ] ||
18670                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18671                 error "stripe count $default_count != $stripe_count for $dir"
18672
18673                 stripe_index=$($LFS getdirstripe -i $dir)
18674                 [ $default_index -eq -1 ] ||
18675                         [ $stripe_index -eq $default_index ] ||
18676                         error "$stripe_index != $default_index for $dir"
18677
18678                 #check default stripe
18679                 stripe_count=$($LFS getdirstripe -D -c $dir)
18680                 [ $stripe_count -eq $default_count ] ||
18681                 error "default count $default_count != $stripe_count for $dir"
18682
18683                 stripe_index=$($LFS getdirstripe -D -i $dir)
18684                 [ $stripe_index -eq $default_index ] ||
18685                 error "default index $default_index != $stripe_index for $dir"
18686         done
18687         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18688 }
18689
18690 test_300g() {
18691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18692         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18693                 skip "Need MDS version at least 2.7.55"
18694
18695         local dir
18696         local stripe_count
18697         local stripe_index
18698
18699         mkdir $DIR/$tdir
18700         mkdir $DIR/$tdir/normal_dir
18701
18702         #Checking when client cache stripe index
18703         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18704         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18705                 error "create striped_dir failed"
18706
18707         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18708                 error "create dir0 fails"
18709         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18710         [ $stripe_index -eq 0 ] ||
18711                 error "dir0 expect index 0 got $stripe_index"
18712
18713         mkdir $DIR/$tdir/striped_dir/dir1 ||
18714                 error "create dir1 fails"
18715         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18716         [ $stripe_index -eq 1 ] ||
18717                 error "dir1 expect index 1 got $stripe_index"
18718
18719         #check default stripe count/stripe index
18720         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18721         test_300_check_default_striped_dir normal_dir 1 0
18722         test_300_check_default_striped_dir normal_dir 2 1
18723         test_300_check_default_striped_dir normal_dir 2 -1
18724
18725         #delete default stripe information
18726         echo "delete default stripeEA"
18727         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18728                 error "set default stripe on striped dir error"
18729
18730         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18731         for dir in $(find $DIR/$tdir/normal_dir/*); do
18732                 stripe_count=$($LFS getdirstripe -c $dir)
18733                 [ $stripe_count -eq 0 ] ||
18734                         error "expect 1 get $stripe_count for $dir"
18735                 stripe_index=$($LFS getdirstripe -i $dir)
18736                 [ $stripe_index -eq 0 ] ||
18737                         error "expect 0 get $stripe_index for $dir"
18738         done
18739 }
18740 run_test 300g "check default striped directory for normal directory"
18741
18742 test_300h() {
18743         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18744         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18745                 skip "Need MDS version at least 2.7.55"
18746
18747         local dir
18748         local stripe_count
18749
18750         mkdir $DIR/$tdir
18751         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18752                 error "set striped dir error"
18753
18754         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18755         test_300_check_default_striped_dir striped_dir 1 0
18756         test_300_check_default_striped_dir striped_dir 2 1
18757         test_300_check_default_striped_dir striped_dir 2 -1
18758
18759         #delete default stripe information
18760         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18761                 error "set default stripe on striped dir error"
18762
18763         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18764         for dir in $(find $DIR/$tdir/striped_dir/*); do
18765                 stripe_count=$($LFS getdirstripe -c $dir)
18766                 [ $stripe_count -eq 0 ] ||
18767                         error "expect 1 get $stripe_count for $dir"
18768         done
18769 }
18770 run_test 300h "check default striped directory for striped directory"
18771
18772 test_300i() {
18773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18774         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18775         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18776                 skip "Need MDS version at least 2.7.55"
18777
18778         local stripe_count
18779         local file
18780
18781         mkdir $DIR/$tdir
18782
18783         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18784                 error "set striped dir error"
18785
18786         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18787                 error "create files under striped dir failed"
18788
18789         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18790                 error "set striped hashdir error"
18791
18792         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18793                 error "create dir0 under hash dir failed"
18794         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18795                 error "create dir1 under hash dir failed"
18796
18797         # unfortunately, we need to umount to clear dir layout cache for now
18798         # once we fully implement dir layout, we can drop this
18799         umount_client $MOUNT || error "umount failed"
18800         mount_client $MOUNT || error "mount failed"
18801
18802         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18803         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18804         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18805
18806         #set the stripe to be unknown hash type
18807         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18808         $LCTL set_param fail_loc=0x1901
18809         for ((i = 0; i < 10; i++)); do
18810                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18811                         error "stat f-$i failed"
18812                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18813         done
18814
18815         touch $DIR/$tdir/striped_dir/f0 &&
18816                 error "create under striped dir with unknown hash should fail"
18817
18818         $LCTL set_param fail_loc=0
18819
18820         umount_client $MOUNT || error "umount failed"
18821         mount_client $MOUNT || error "mount failed"
18822
18823         return 0
18824 }
18825 run_test 300i "client handle unknown hash type striped directory"
18826
18827 test_300j() {
18828         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18829         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18830         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18831                 skip "Need MDS version at least 2.7.55"
18832
18833         local stripe_count
18834         local file
18835
18836         mkdir $DIR/$tdir
18837
18838         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18839         $LCTL set_param fail_loc=0x1702
18840         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18841                 error "set striped dir error"
18842
18843         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18844                 error "create files under striped dir failed"
18845
18846         $LCTL set_param fail_loc=0
18847
18848         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18849
18850         return 0
18851 }
18852 run_test 300j "test large update record"
18853
18854 test_300k() {
18855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18856         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18857         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18858                 skip "Need MDS version at least 2.7.55"
18859
18860         # this test needs a huge transaction
18861         local kb
18862         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18863         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18864
18865         local stripe_count
18866         local file
18867
18868         mkdir $DIR/$tdir
18869
18870         #define OBD_FAIL_LARGE_STRIPE   0x1703
18871         $LCTL set_param fail_loc=0x1703
18872         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18873                 error "set striped dir error"
18874         $LCTL set_param fail_loc=0
18875
18876         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18877                 error "getstripeddir fails"
18878         rm -rf $DIR/$tdir/striped_dir ||
18879                 error "unlink striped dir fails"
18880
18881         return 0
18882 }
18883 run_test 300k "test large striped directory"
18884
18885 test_300l() {
18886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18887         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18888         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18889                 skip "Need MDS version at least 2.7.55"
18890
18891         local stripe_index
18892
18893         test_mkdir -p $DIR/$tdir/striped_dir
18894         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18895                         error "chown $RUNAS_ID failed"
18896         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18897                 error "set default striped dir failed"
18898
18899         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18900         $LCTL set_param fail_loc=0x80000158
18901         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18902
18903         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18904         [ $stripe_index -eq 1 ] ||
18905                 error "expect 1 get $stripe_index for $dir"
18906 }
18907 run_test 300l "non-root user to create dir under striped dir with stale layout"
18908
18909 test_300m() {
18910         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18911         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18912         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18913                 skip "Need MDS version at least 2.7.55"
18914
18915         mkdir -p $DIR/$tdir/striped_dir
18916         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18917                 error "set default stripes dir error"
18918
18919         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18920
18921         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18922         [ $stripe_count -eq 0 ] ||
18923                         error "expect 0 get $stripe_count for a"
18924
18925         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18926                 error "set default stripes dir error"
18927
18928         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18929
18930         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18931         [ $stripe_count -eq 0 ] ||
18932                         error "expect 0 get $stripe_count for b"
18933
18934         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18935                 error "set default stripes dir error"
18936
18937         mkdir $DIR/$tdir/striped_dir/c &&
18938                 error "default stripe_index is invalid, mkdir c should fails"
18939
18940         rm -rf $DIR/$tdir || error "rmdir fails"
18941 }
18942 run_test 300m "setstriped directory on single MDT FS"
18943
18944 cleanup_300n() {
18945         local list=$(comma_list $(mdts_nodes))
18946
18947         trap 0
18948         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18949 }
18950
18951 test_300n() {
18952         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18953         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18954         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18955                 skip "Need MDS version at least 2.7.55"
18956         remote_mds_nodsh && skip "remote MDS with nodsh"
18957
18958         local stripe_index
18959         local list=$(comma_list $(mdts_nodes))
18960
18961         trap cleanup_300n RETURN EXIT
18962         mkdir -p $DIR/$tdir
18963         chmod 777 $DIR/$tdir
18964         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18965                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18966                 error "create striped dir succeeds with gid=0"
18967
18968         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18969         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18970                 error "create striped dir fails with gid=-1"
18971
18972         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18973         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18974                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18975                 error "set default striped dir succeeds with gid=0"
18976
18977
18978         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18979         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18980                 error "set default striped dir fails with gid=-1"
18981
18982
18983         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18984         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18985                                         error "create test_dir fails"
18986         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18987                                         error "create test_dir1 fails"
18988         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18989                                         error "create test_dir2 fails"
18990         cleanup_300n
18991 }
18992 run_test 300n "non-root user to create dir under striped dir with default EA"
18993
18994 test_300o() {
18995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18996         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18997         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18998                 skip "Need MDS version at least 2.7.55"
18999
19000         local numfree1
19001         local numfree2
19002
19003         mkdir -p $DIR/$tdir
19004
19005         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19006         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19007         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19008                 skip "not enough free inodes $numfree1 $numfree2"
19009         fi
19010
19011         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19012         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19013         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19014                 skip "not enough free space $numfree1 $numfree2"
19015         fi
19016
19017         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19018                 error "setdirstripe fails"
19019
19020         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19021                 error "create dirs fails"
19022
19023         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19024         ls $DIR/$tdir/striped_dir > /dev/null ||
19025                 error "ls striped dir fails"
19026         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19027                 error "unlink big striped dir fails"
19028 }
19029 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19030
19031 test_300p() {
19032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19033         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19034         remote_mds_nodsh && skip "remote MDS with nodsh"
19035
19036         mkdir -p $DIR/$tdir
19037
19038         #define OBD_FAIL_OUT_ENOSPC     0x1704
19039         do_facet mds2 lctl set_param fail_loc=0x80001704
19040         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19041                  && error "create striped directory should fail"
19042
19043         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19044
19045         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19046         true
19047 }
19048 run_test 300p "create striped directory without space"
19049
19050 test_300q() {
19051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19052         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19053
19054         local fd=$(free_fd)
19055         local cmd="exec $fd<$tdir"
19056         cd $DIR
19057         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19058         eval $cmd
19059         cmd="exec $fd<&-"
19060         trap "eval $cmd" EXIT
19061         cd $tdir || error "cd $tdir fails"
19062         rmdir  ../$tdir || error "rmdir $tdir fails"
19063         mkdir local_dir && error "create dir succeeds"
19064         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19065         eval $cmd
19066         return 0
19067 }
19068 run_test 300q "create remote directory under orphan directory"
19069
19070 test_300r() {
19071         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19072                 skip "Need MDS version at least 2.7.55" && return
19073         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19074
19075         mkdir $DIR/$tdir
19076
19077         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19078                 error "set striped dir error"
19079
19080         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19081                 error "getstripeddir fails"
19082
19083         local stripe_count
19084         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19085                       awk '/lmv_stripe_count:/ { print $2 }')
19086
19087         [ $MDSCOUNT -ne $stripe_count ] &&
19088                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19089
19090         rm -rf $DIR/$tdir/striped_dir ||
19091                 error "unlink striped dir fails"
19092 }
19093 run_test 300r "test -1 striped directory"
19094
19095 prepare_remote_file() {
19096         mkdir $DIR/$tdir/src_dir ||
19097                 error "create remote source failed"
19098
19099         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19100                  error "cp to remote source failed"
19101         touch $DIR/$tdir/src_dir/a
19102
19103         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19104                 error "create remote target dir failed"
19105
19106         touch $DIR/$tdir/tgt_dir/b
19107
19108         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19109                 error "rename dir cross MDT failed!"
19110
19111         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19112                 error "src_child still exists after rename"
19113
19114         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19115                 error "missing file(a) after rename"
19116
19117         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19118                 error "diff after rename"
19119 }
19120
19121 test_310a() {
19122         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19124
19125         local remote_file=$DIR/$tdir/tgt_dir/b
19126
19127         mkdir -p $DIR/$tdir
19128
19129         prepare_remote_file || error "prepare remote file failed"
19130
19131         #open-unlink file
19132         $OPENUNLINK $remote_file $remote_file ||
19133                 error "openunlink $remote_file failed"
19134         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19135 }
19136 run_test 310a "open unlink remote file"
19137
19138 test_310b() {
19139         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19141
19142         local remote_file=$DIR/$tdir/tgt_dir/b
19143
19144         mkdir -p $DIR/$tdir
19145
19146         prepare_remote_file || error "prepare remote file failed"
19147
19148         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19149         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19150         $CHECKSTAT -t file $remote_file || error "check file failed"
19151 }
19152 run_test 310b "unlink remote file with multiple links while open"
19153
19154 test_310c() {
19155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19156         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19157
19158         local remote_file=$DIR/$tdir/tgt_dir/b
19159
19160         mkdir -p $DIR/$tdir
19161
19162         prepare_remote_file || error "prepare remote file failed"
19163
19164         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19165         multiop_bg_pause $remote_file O_uc ||
19166                         error "mulitop failed for remote file"
19167         MULTIPID=$!
19168         $MULTIOP $DIR/$tfile Ouc
19169         kill -USR1 $MULTIPID
19170         wait $MULTIPID
19171 }
19172 run_test 310c "open-unlink remote file with multiple links"
19173
19174 #LU-4825
19175 test_311() {
19176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19177         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19178         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19179                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19180         remote_mds_nodsh && skip "remote MDS with nodsh"
19181
19182         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19183         local mdts=$(comma_list $(mdts_nodes))
19184
19185         mkdir -p $DIR/$tdir
19186         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19187         createmany -o $DIR/$tdir/$tfile. 1000
19188
19189         # statfs data is not real time, let's just calculate it
19190         old_iused=$((old_iused + 1000))
19191
19192         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19193                         osp.*OST0000*MDT0000.create_count")
19194         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19195                                 osp.*OST0000*MDT0000.max_create_count")
19196         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19197
19198         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19199         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19200         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19201
19202         unlinkmany $DIR/$tdir/$tfile. 1000
19203
19204         do_nodes $mdts "$LCTL set_param -n \
19205                         osp.*OST0000*.max_create_count=$max_count"
19206         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19207                 do_nodes $mdts "$LCTL set_param -n \
19208                                 osp.*OST0000*.create_count=$count"
19209         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19210                         grep "=0" && error "create_count is zero"
19211
19212         local new_iused
19213         for i in $(seq 120); do
19214                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19215                 # system may be too busy to destroy all objs in time, use
19216                 # a somewhat small value to not fail autotest
19217                 [ $((old_iused - new_iused)) -gt 400 ] && break
19218                 sleep 1
19219         done
19220
19221         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19222         [ $((old_iused - new_iused)) -gt 400 ] ||
19223                 error "objs not destroyed after unlink"
19224 }
19225 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19226
19227 zfs_oid_to_objid()
19228 {
19229         local ost=$1
19230         local objid=$2
19231
19232         local vdevdir=$(dirname $(facet_vdevice $ost))
19233         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19234         local zfs_zapid=$(do_facet $ost $cmd |
19235                           grep -w "/O/0/d$((objid%32))" -C 5 |
19236                           awk '/Object/{getline; print $1}')
19237         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19238                           awk "/$objid = /"'{printf $3}')
19239
19240         echo $zfs_objid
19241 }
19242
19243 zfs_object_blksz() {
19244         local ost=$1
19245         local objid=$2
19246
19247         local vdevdir=$(dirname $(facet_vdevice $ost))
19248         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19249         local blksz=$(do_facet $ost $cmd $objid |
19250                       awk '/dblk/{getline; printf $4}')
19251
19252         case "${blksz: -1}" in
19253                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19254                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19255                 *) ;;
19256         esac
19257
19258         echo $blksz
19259 }
19260
19261 test_312() { # LU-4856
19262         remote_ost_nodsh && skip "remote OST with nodsh"
19263         [ "$ost1_FSTYPE" = "zfs" ] ||
19264                 skip_env "the test only applies to zfs"
19265
19266         local max_blksz=$(do_facet ost1 \
19267                           $ZFS get -p recordsize $(facet_device ost1) |
19268                           awk '!/VALUE/{print $3}')
19269
19270         # to make life a little bit easier
19271         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19272         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19273
19274         local tf=$DIR/$tdir/$tfile
19275         touch $tf
19276         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19277
19278         # Get ZFS object id
19279         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19280         # block size change by sequential overwrite
19281         local bs
19282
19283         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19284                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19285
19286                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19287                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19288         done
19289         rm -f $tf
19290
19291         # block size change by sequential append write
19292         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19293         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19294         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19295         local count
19296
19297         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19298                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19299                         oflag=sync conv=notrunc
19300
19301                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19302                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19303                         error "blksz error, actual $blksz, " \
19304                                 "expected: 2 * $count * $PAGE_SIZE"
19305         done
19306         rm -f $tf
19307
19308         # random write
19309         touch $tf
19310         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19311         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19312
19313         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19314         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19315         [ $blksz -eq $PAGE_SIZE ] ||
19316                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19317
19318         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19319         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19320         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19321
19322         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19323         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19324         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19325 }
19326 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19327
19328 test_313() {
19329         remote_ost_nodsh && skip "remote OST with nodsh"
19330
19331         local file=$DIR/$tfile
19332
19333         rm -f $file
19334         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19335
19336         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19337         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19338         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19339                 error "write should failed"
19340         do_facet ost1 "$LCTL set_param fail_loc=0"
19341         rm -f $file
19342 }
19343 run_test 313 "io should fail after last_rcvd update fail"
19344
19345 test_314() {
19346         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19347
19348         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19349         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19350         rm -f $DIR/$tfile
19351         wait_delete_completed
19352         do_facet ost1 "$LCTL set_param fail_loc=0"
19353 }
19354 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19355
19356 test_315() { # LU-618
19357         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19358
19359         local file=$DIR/$tfile
19360         rm -f $file
19361
19362         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19363                 error "multiop file write failed"
19364         $MULTIOP $file oO_RDONLY:r4063232_c &
19365         PID=$!
19366
19367         sleep 2
19368
19369         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19370         kill -USR1 $PID
19371
19372         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19373         rm -f $file
19374 }
19375 run_test 315 "read should be accounted"
19376
19377 test_316() {
19378         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19379         large_xattr_enabled || skip_env "ea_inode feature disabled"
19380
19381         rm -rf $DIR/$tdir/d
19382         mkdir -p $DIR/$tdir/d
19383         chown nobody $DIR/$tdir/d
19384         touch $DIR/$tdir/d/file
19385
19386         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19387 }
19388 run_test 316 "lfs mv"
19389
19390 test_317() {
19391         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19392                 skip "Need MDS version at least 2.11.53"
19393         if [ "$ost1_FSTYPE" == "zfs" ]; then
19394                 skip "LU-10370: no implementation for ZFS"
19395         fi
19396
19397         local trunc_sz
19398         local grant_blk_size
19399
19400         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19401                         awk '/grant_block_size:/ { print $2; exit; }')
19402         #
19403         # Create File of size 5M. Truncate it to below size's and verify
19404         # blocks count.
19405         #
19406         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19407                 error "Create file $DIR/$tfile failed"
19408         stack_trap "rm -f $DIR/$tfile" EXIT
19409
19410         for trunc_sz in 2097152 4097 4000 509 0; do
19411                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19412                         error "truncate $tfile to $trunc_sz failed"
19413                 local sz=$(stat --format=%s $DIR/$tfile)
19414                 local blk=$(stat --format=%b $DIR/$tfile)
19415                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19416                                      grant_blk_size) * 8))
19417
19418                 if [[ $blk -ne $trunc_blk ]]; then
19419                         $(which stat) $DIR/$tfile
19420                         error "Expected Block $trunc_blk got $blk for $tfile"
19421                 fi
19422
19423                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19424                         error "Expected Size $trunc_sz got $sz for $tfile"
19425         done
19426
19427         #
19428         # sparse file test
19429         # Create file with a hole and write actual two blocks. Block count
19430         # must be 16.
19431         #
19432         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19433                 conv=fsync || error "Create file : $DIR/$tfile"
19434
19435         # Calculate the final truncate size.
19436         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19437
19438         #
19439         # truncate to size $trunc_sz bytes. Strip the last block
19440         # The block count must drop to 8
19441         #
19442         $TRUNCATE $DIR/$tfile $trunc_sz ||
19443                 error "truncate $tfile to $trunc_sz failed"
19444
19445         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19446         sz=$(stat --format=%s $DIR/$tfile)
19447         blk=$(stat --format=%b $DIR/$tfile)
19448
19449         if [[ $blk -ne $trunc_bsz ]]; then
19450                 $(which stat) $DIR/$tfile
19451                 error "Expected Block $trunc_bsz got $blk for $tfile"
19452         fi
19453
19454         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19455                 error "Expected Size $trunc_sz got $sz for $tfile"
19456 }
19457 run_test 317 "Verify blocks get correctly update after truncate"
19458
19459 test_318() {
19460         local old_max_active=$($LCTL get_param -n \
19461                             llite.*.max_read_ahead_async_active 2>/dev/null)
19462
19463         $LCTL set_param llite.*.max_read_ahead_async_active=256
19464         local max_active=$($LCTL get_param -n \
19465                            llite.*.max_read_ahead_async_active 2>/dev/null)
19466         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19467
19468         # currently reset to 0 is unsupported, leave it 512 for now.
19469         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19470                 error "set max_read_ahead_async_active should fail"
19471
19472         $LCTL set_param llite.*.max_read_ahead_async_active=512
19473         max_active=$($LCTL get_param -n \
19474                      llite.*.max_read_ahead_async_active 2>/dev/null)
19475         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19476
19477         # restore @max_active
19478         [ $old_max_active -ne 0 ] && $LCTL set_param \
19479                 llite.*.max_read_ahead_async_active=$old_max_active
19480
19481         local old_threshold=$($LCTL get_param -n \
19482                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19483         local max_per_file_mb=$($LCTL get_param -n \
19484                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19485
19486         local invalid=$(($max_per_file_mb + 1))
19487         $LCTL set_param \
19488                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19489                         && error "set $invalid should fail"
19490
19491         local valid=$(($invalid - 1))
19492         $LCTL set_param \
19493                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19494                         error "set $valid should succeed"
19495         local threshold=$($LCTL get_param -n \
19496                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19497         [ $threshold -eq $valid ] || error \
19498                 "expect threshold $valid got $threshold"
19499         $LCTL set_param \
19500                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19501 }
19502 run_test 318 "Verify async readahead tunables"
19503
19504 test_319() {
19505         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19506
19507         local before=$(date +%s)
19508         local evict
19509         local mdir=$DIR/$tdir
19510         local file=$mdir/xxx
19511
19512         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19513         touch $file
19514
19515 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19516         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19517         $LFS mv -m1 $file &
19518
19519         sleep 1
19520         dd if=$file of=/dev/null
19521         wait
19522         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19523           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19524
19525         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19526 }
19527 run_test 319 "lost lease lock on migrate error"
19528
19529 test_fake_rw() {
19530         local read_write=$1
19531         if [ "$read_write" = "write" ]; then
19532                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19533         elif [ "$read_write" = "read" ]; then
19534                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19535         else
19536                 error "argument error"
19537         fi
19538
19539         # turn off debug for performance testing
19540         local saved_debug=$($LCTL get_param -n debug)
19541         $LCTL set_param debug=0
19542
19543         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19544
19545         # get ost1 size - lustre-OST0000
19546         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19547         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19548         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19549
19550         if [ "$read_write" = "read" ]; then
19551                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19552         fi
19553
19554         local start_time=$(date +%s.%N)
19555         $dd_cmd bs=1M count=$blocks oflag=sync ||
19556                 error "real dd $read_write error"
19557         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19558
19559         if [ "$read_write" = "write" ]; then
19560                 rm -f $DIR/$tfile
19561         fi
19562
19563         # define OBD_FAIL_OST_FAKE_RW           0x238
19564         do_facet ost1 $LCTL set_param fail_loc=0x238
19565
19566         local start_time=$(date +%s.%N)
19567         $dd_cmd bs=1M count=$blocks oflag=sync ||
19568                 error "fake dd $read_write error"
19569         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19570
19571         if [ "$read_write" = "write" ]; then
19572                 # verify file size
19573                 cancel_lru_locks osc
19574                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19575                         error "$tfile size not $blocks MB"
19576         fi
19577         do_facet ost1 $LCTL set_param fail_loc=0
19578
19579         echo "fake $read_write $duration_fake vs. normal $read_write" \
19580                 "$duration in seconds"
19581         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19582                 error_not_in_vm "fake write is slower"
19583
19584         $LCTL set_param -n debug="$saved_debug"
19585         rm -f $DIR/$tfile
19586 }
19587 test_399a() { # LU-7655 for OST fake write
19588         remote_ost_nodsh && skip "remote OST with nodsh"
19589
19590         test_fake_rw write
19591 }
19592 run_test 399a "fake write should not be slower than normal write"
19593
19594 test_399b() { # LU-8726 for OST fake read
19595         remote_ost_nodsh && skip "remote OST with nodsh"
19596         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19597                 skip_env "ldiskfs only test"
19598         fi
19599
19600         test_fake_rw read
19601 }
19602 run_test 399b "fake read should not be slower than normal read"
19603
19604 test_400a() { # LU-1606, was conf-sanity test_74
19605         if ! which $CC > /dev/null 2>&1; then
19606                 skip_env "$CC is not installed"
19607         fi
19608
19609         local extra_flags=''
19610         local out=$TMP/$tfile
19611         local prefix=/usr/include/lustre
19612         local prog
19613
19614         if ! [[ -d $prefix ]]; then
19615                 # Assume we're running in tree and fixup the include path.
19616                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19617                 extra_flags+=" -L$LUSTRE/utils/.lib"
19618         fi
19619
19620         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19621                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19622                         error "client api broken"
19623         done
19624         rm -f $out
19625 }
19626 run_test 400a "Lustre client api program can compile and link"
19627
19628 test_400b() { # LU-1606, LU-5011
19629         local header
19630         local out=$TMP/$tfile
19631         local prefix=/usr/include/linux/lustre
19632
19633         # We use a hard coded prefix so that this test will not fail
19634         # when run in tree. There are headers in lustre/include/lustre/
19635         # that are not packaged (like lustre_idl.h) and have more
19636         # complicated include dependencies (like config.h and lnet/types.h).
19637         # Since this test about correct packaging we just skip them when
19638         # they don't exist (see below) rather than try to fixup cppflags.
19639
19640         if ! which $CC > /dev/null 2>&1; then
19641                 skip_env "$CC is not installed"
19642         fi
19643
19644         for header in $prefix/*.h; do
19645                 if ! [[ -f "$header" ]]; then
19646                         continue
19647                 fi
19648
19649                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19650                         continue # lustre_ioctl.h is internal header
19651                 fi
19652
19653                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19654                         error "cannot compile '$header'"
19655         done
19656         rm -f $out
19657 }
19658 run_test 400b "packaged headers can be compiled"
19659
19660 test_401a() { #LU-7437
19661         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19662         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19663
19664         #count the number of parameters by "list_param -R"
19665         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19666         #count the number of parameters by listing proc files
19667         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19668         echo "proc_dirs='$proc_dirs'"
19669         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19670         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19671                       sort -u | wc -l)
19672
19673         [ $params -eq $procs ] ||
19674                 error "found $params parameters vs. $procs proc files"
19675
19676         # test the list_param -D option only returns directories
19677         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19678         #count the number of parameters by listing proc directories
19679         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19680                 sort -u | wc -l)
19681
19682         [ $params -eq $procs ] ||
19683                 error "found $params parameters vs. $procs proc files"
19684 }
19685 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19686
19687 test_401b() {
19688         local save=$($LCTL get_param -n jobid_var)
19689         local tmp=testing
19690
19691         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19692                 error "no error returned when setting bad parameters"
19693
19694         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19695         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19696
19697         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19698         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19699         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19700 }
19701 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19702
19703 test_401c() {
19704         local jobid_var_old=$($LCTL get_param -n jobid_var)
19705         local jobid_var_new
19706
19707         $LCTL set_param jobid_var= &&
19708                 error "no error returned for 'set_param a='"
19709
19710         jobid_var_new=$($LCTL get_param -n jobid_var)
19711         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19712                 error "jobid_var was changed by setting without value"
19713
19714         $LCTL set_param jobid_var &&
19715                 error "no error returned for 'set_param a'"
19716
19717         jobid_var_new=$($LCTL get_param -n jobid_var)
19718         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19719                 error "jobid_var was changed by setting without value"
19720 }
19721 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19722
19723 test_401d() {
19724         local jobid_var_old=$($LCTL get_param -n jobid_var)
19725         local jobid_var_new
19726         local new_value="foo=bar"
19727
19728         $LCTL set_param jobid_var=$new_value ||
19729                 error "'set_param a=b' did not accept a value containing '='"
19730
19731         jobid_var_new=$($LCTL get_param -n jobid_var)
19732         [[ "$jobid_var_new" == "$new_value" ]] ||
19733                 error "'set_param a=b' failed on a value containing '='"
19734
19735         # Reset the jobid_var to test the other format
19736         $LCTL set_param jobid_var=$jobid_var_old
19737         jobid_var_new=$($LCTL get_param -n jobid_var)
19738         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19739                 error "failed to reset jobid_var"
19740
19741         $LCTL set_param jobid_var $new_value ||
19742                 error "'set_param a b' did not accept a value containing '='"
19743
19744         jobid_var_new=$($LCTL get_param -n jobid_var)
19745         [[ "$jobid_var_new" == "$new_value" ]] ||
19746                 error "'set_param a b' failed on a value containing '='"
19747
19748         $LCTL set_param jobid_var $jobid_var_old
19749         jobid_var_new=$($LCTL get_param -n jobid_var)
19750         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19751                 error "failed to reset jobid_var"
19752 }
19753 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19754
19755 test_402() {
19756         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19757         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19758                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19759         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19760                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19761                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19762         remote_mds_nodsh && skip "remote MDS with nodsh"
19763
19764         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19765 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19766         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19767         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19768                 echo "Touch failed - OK"
19769 }
19770 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19771
19772 test_403() {
19773         local file1=$DIR/$tfile.1
19774         local file2=$DIR/$tfile.2
19775         local tfile=$TMP/$tfile
19776
19777         rm -f $file1 $file2 $tfile
19778
19779         touch $file1
19780         ln $file1 $file2
19781
19782         # 30 sec OBD_TIMEOUT in ll_getattr()
19783         # right before populating st_nlink
19784         $LCTL set_param fail_loc=0x80001409
19785         stat -c %h $file1 > $tfile &
19786
19787         # create an alias, drop all locks and reclaim the dentry
19788         < $file2
19789         cancel_lru_locks mdc
19790         cancel_lru_locks osc
19791         sysctl -w vm.drop_caches=2
19792
19793         wait
19794
19795         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19796
19797         rm -f $tfile $file1 $file2
19798 }
19799 run_test 403 "i_nlink should not drop to zero due to aliasing"
19800
19801 test_404() { # LU-6601
19802         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19803                 skip "Need server version newer than 2.8.52"
19804         remote_mds_nodsh && skip "remote MDS with nodsh"
19805
19806         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19807                 awk '/osp .*-osc-MDT/ { print $4}')
19808
19809         local osp
19810         for osp in $mosps; do
19811                 echo "Deactivate: " $osp
19812                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19813                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19814                         awk -vp=$osp '$4 == p { print $2 }')
19815                 [ $stat = IN ] || {
19816                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19817                         error "deactivate error"
19818                 }
19819                 echo "Activate: " $osp
19820                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19821                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19822                         awk -vp=$osp '$4 == p { print $2 }')
19823                 [ $stat = UP ] || {
19824                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19825                         error "activate error"
19826                 }
19827         done
19828 }
19829 run_test 404 "validate manual {de}activated works properly for OSPs"
19830
19831 test_405() {
19832         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19833         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19834                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19835                         skip "Layout swap lock is not supported"
19836
19837         check_swap_layouts_support
19838
19839         test_mkdir $DIR/$tdir
19840         swap_lock_test -d $DIR/$tdir ||
19841                 error "One layout swap locked test failed"
19842 }
19843 run_test 405 "Various layout swap lock tests"
19844
19845 test_406() {
19846         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19847         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19848         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19849         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19850         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19851                 skip "Need MDS version at least 2.8.50"
19852
19853         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19854         local test_pool=$TESTNAME
19855
19856         if ! combined_mgs_mds ; then
19857                 mount_mgs_client
19858         fi
19859         pool_add $test_pool || error "pool_add failed"
19860         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19861                 error "pool_add_targets failed"
19862
19863         save_layout_restore_at_exit $MOUNT
19864
19865         # parent set default stripe count only, child will stripe from both
19866         # parent and fs default
19867         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19868                 error "setstripe $MOUNT failed"
19869         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19870         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19871         for i in $(seq 10); do
19872                 local f=$DIR/$tdir/$tfile.$i
19873                 touch $f || error "touch failed"
19874                 local count=$($LFS getstripe -c $f)
19875                 [ $count -eq $OSTCOUNT ] ||
19876                         error "$f stripe count $count != $OSTCOUNT"
19877                 local offset=$($LFS getstripe -i $f)
19878                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19879                 local size=$($LFS getstripe -S $f)
19880                 [ $size -eq $((def_stripe_size * 2)) ] ||
19881                         error "$f stripe size $size != $((def_stripe_size * 2))"
19882                 local pool=$($LFS getstripe -p $f)
19883                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19884         done
19885
19886         # change fs default striping, delete parent default striping, now child
19887         # will stripe from new fs default striping only
19888         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19889                 error "change $MOUNT default stripe failed"
19890         $LFS setstripe -c 0 $DIR/$tdir ||
19891                 error "delete $tdir default stripe failed"
19892         for i in $(seq 11 20); do
19893                 local f=$DIR/$tdir/$tfile.$i
19894                 touch $f || error "touch $f failed"
19895                 local count=$($LFS getstripe -c $f)
19896                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19897                 local offset=$($LFS getstripe -i $f)
19898                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19899                 local size=$($LFS getstripe -S $f)
19900                 [ $size -eq $def_stripe_size ] ||
19901                         error "$f stripe size $size != $def_stripe_size"
19902                 local pool=$($LFS getstripe -p $f)
19903                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19904         done
19905
19906         unlinkmany $DIR/$tdir/$tfile. 1 20
19907
19908         local f=$DIR/$tdir/$tfile
19909         pool_remove_all_targets $test_pool $f
19910         pool_remove $test_pool $f
19911
19912         if ! combined_mgs_mds ; then
19913                 umount_mgs_client
19914         fi
19915 }
19916 run_test 406 "DNE support fs default striping"
19917
19918 test_407() {
19919         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19920         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19921                 skip "Need MDS version at least 2.8.55"
19922         remote_mds_nodsh && skip "remote MDS with nodsh"
19923
19924         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19925                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19926         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19927                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19928         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19929
19930         #define OBD_FAIL_DT_TXN_STOP    0x2019
19931         for idx in $(seq $MDSCOUNT); do
19932                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19933         done
19934         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19935         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19936                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19937         true
19938 }
19939 run_test 407 "transaction fail should cause operation fail"
19940
19941 test_408() {
19942         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19943
19944         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19945         lctl set_param fail_loc=0x8000040a
19946         # let ll_prepare_partial_page() fail
19947         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19948
19949         rm -f $DIR/$tfile
19950
19951         # create at least 100 unused inodes so that
19952         # shrink_icache_memory(0) should not return 0
19953         touch $DIR/$tfile-{0..100}
19954         rm -f $DIR/$tfile-{0..100}
19955         sync
19956
19957         echo 2 > /proc/sys/vm/drop_caches
19958 }
19959 run_test 408 "drop_caches should not hang due to page leaks"
19960
19961 test_409()
19962 {
19963         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19964
19965         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19966         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19967         touch $DIR/$tdir/guard || error "(2) Fail to create"
19968
19969         local PREFIX=$(str_repeat 'A' 128)
19970         echo "Create 1K hard links start at $(date)"
19971         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19972                 error "(3) Fail to hard link"
19973
19974         echo "Links count should be right although linkEA overflow"
19975         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19976         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19977         [ $linkcount -eq 1001 ] ||
19978                 error "(5) Unexpected hard links count: $linkcount"
19979
19980         echo "List all links start at $(date)"
19981         ls -l $DIR/$tdir/foo > /dev/null ||
19982                 error "(6) Fail to list $DIR/$tdir/foo"
19983
19984         echo "Unlink hard links start at $(date)"
19985         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19986                 error "(7) Fail to unlink"
19987         echo "Unlink hard links finished at $(date)"
19988 }
19989 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19990
19991 test_410()
19992 {
19993         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19994                 skip "Need client version at least 2.9.59"
19995
19996         # Create a file, and stat it from the kernel
19997         local testfile=$DIR/$tfile
19998         touch $testfile
19999
20000         local run_id=$RANDOM
20001         local my_ino=$(stat --format "%i" $testfile)
20002
20003         # Try to insert the module. This will always fail as the
20004         # module is designed to not be inserted.
20005         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20006             &> /dev/null
20007
20008         # Anything but success is a test failure
20009         dmesg | grep -q \
20010             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20011             error "no inode match"
20012 }
20013 run_test 410 "Test inode number returned from kernel thread"
20014
20015 cleanup_test411_cgroup() {
20016         trap 0
20017         rmdir "$1"
20018 }
20019
20020 test_411() {
20021         local cg_basedir=/sys/fs/cgroup/memory
20022         # LU-9966
20023         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20024                 skip "no setup for cgroup"
20025
20026         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20027                 error "test file creation failed"
20028         cancel_lru_locks osc
20029
20030         # Create a very small memory cgroup to force a slab allocation error
20031         local cgdir=$cg_basedir/osc_slab_alloc
20032         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20033         trap "cleanup_test411_cgroup $cgdir" EXIT
20034         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20035         echo 1M > $cgdir/memory.limit_in_bytes
20036
20037         # Should not LBUG, just be killed by oom-killer
20038         # dd will return 0 even allocation failure in some environment.
20039         # So don't check return value
20040         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20041         cleanup_test411_cgroup $cgdir
20042
20043         return 0
20044 }
20045 run_test 411 "Slab allocation error with cgroup does not LBUG"
20046
20047 test_412() {
20048         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20049         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20050                 skip "Need server version at least 2.10.55"
20051         fi
20052
20053         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20054                 error "mkdir failed"
20055         $LFS getdirstripe $DIR/$tdir
20056         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20057         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20058                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20059         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20060         [ $stripe_count -eq 2 ] ||
20061                 error "expect 2 get $stripe_count"
20062 }
20063 run_test 412 "mkdir on specific MDTs"
20064
20065 test_413a() {
20066         [ $MDSCOUNT -lt 2 ] &&
20067                 skip "We need at least 2 MDTs for this test"
20068
20069         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20070                 skip "Need server version at least 2.10.55"
20071         fi
20072
20073         mkdir $DIR/$tdir || error "mkdir failed"
20074
20075         # find MDT that is the most full
20076         local max=$($LFS df | grep MDT |
20077                 awk 'BEGIN { a=0 }
20078                         { sub("%", "", $5)
20079                           if (0+$5 >= a)
20080                           {
20081                                 a = $5
20082                                 b = $6
20083                           }
20084                         }
20085                      END { split(b, c, ":")
20086                            sub("]", "", c[2])
20087                            print c[2]
20088                          }')
20089
20090         for i in $(seq $((MDSCOUNT - 1))); do
20091                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20092                         error "mkdir d$i failed"
20093                 $LFS getdirstripe $DIR/$tdir/d$i
20094                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20095                 [ $stripe_index -ne $max ] ||
20096                         error "don't expect $max"
20097         done
20098 }
20099 run_test 413a "mkdir on less full MDTs"
20100
20101 test_413b() {
20102         [ $MDSCOUNT -lt 2 ] &&
20103                 skip "We need at least 2 MDTs for this test"
20104
20105         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20106                 skip "Need server version at least 2.12.52"
20107
20108         mkdir $DIR/$tdir || error "mkdir failed"
20109         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20110                 error "setdirstripe failed"
20111
20112         local qos_prio_free
20113         local qos_threshold_rr
20114         local count
20115
20116         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20117         qos_prio_free=${qos_prio_free%%%}
20118         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20119         qos_threshold_rr=${qos_threshold_rr%%%}
20120         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20121
20122         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20123         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20124                 EXIT
20125         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20126
20127         echo "mkdir with roundrobin"
20128
20129         $LCTL set_param lmv.*.qos_threshold_rr=100
20130         for i in $(seq $((100 * MDSCOUNT))); do
20131                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20132         done
20133         for i in $(seq $MDSCOUNT); do
20134                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20135                         wc -w)
20136                 echo "$count directories created on MDT$((i - 1))"
20137                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20138         done
20139
20140         rm -rf $DIR/$tdir/*
20141
20142         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20143         # Shorten statfs result age, so that it can be updated in time
20144         $LCTL set_param lmv.*.qos_maxage=1
20145         sleep_maxage
20146
20147         local ffree
20148         local max
20149         local min
20150         local max_index
20151         local min_index
20152
20153         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20154         echo "MDT filesfree available: ${ffree[@]}"
20155         max=${ffree[0]}
20156         min=${ffree[0]}
20157         max_index=0
20158         min_index=0
20159         for ((i = 0; i < ${#ffree[@]}; i++)); do
20160                 if [[ ${ffree[i]} -gt $max ]]; then
20161                         max=${ffree[i]}
20162                         max_index=$i
20163                 fi
20164                 if [[ ${ffree[i]} -lt $min ]]; then
20165                         min=${ffree[i]}
20166                         min_index=$i
20167                 fi
20168         done
20169         echo "Min free files: MDT$min_index: $min"
20170         echo "Max free files: MDT$max_index: $max"
20171
20172         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20173         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20174
20175         # Check if we need to generate uneven MDTs
20176         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20177         local threshold=10
20178         local diff=$((max - min))
20179         local diff2=$((diff * 100 / min))
20180
20181         echo -n "Check for uneven MDTs: "
20182         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20183
20184         if [ $diff2 -gt $threshold ]; then
20185                 echo "ok"
20186                 echo "Don't need to fill MDT$min_index"
20187         else
20188                 # generate uneven MDTs, create till 25% diff
20189                 echo "no"
20190                 diff2=$((threshold - diff2))
20191                 diff=$((min * diff2 / 100))
20192                 # 50 sec per 10000 files in vm
20193                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20194                         skip "$diff files to create"
20195                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20196                 local i
20197                 local value="$(generate_string 1024)"
20198                 for i in $(seq $diff); do
20199                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20200                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20201                                 error "create f$i failed"
20202                         setfattr -n user.413b -v $value \
20203                                 $DIR/$tdir-MDT$min_index/f$i ||
20204                                 error "setfattr f$i failed"
20205                 done
20206         fi
20207
20208         min=$((100 *MDSCOUNT))
20209         max=0
20210
20211         echo "mkdir with balanced space usage"
20212         $LCTL set_param lmv.*.qos_prio_free=100
20213         for i in $(seq $((100 * MDSCOUNT))); do
20214                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20215         done
20216         for i in $(seq $MDSCOUNT); do
20217                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20218                         wc -w)
20219                 echo "$count directories created on MDT$((i - 1))"
20220                 [ $min -gt $count ] && min=$count
20221                 [ $max -lt $count ] && max=$count
20222         done
20223         [ $((max - min)) -gt $MDSCOUNT ] ||
20224                 error "subdirs shouldn't be evenly distributed"
20225
20226         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20227
20228         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20229         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20230         true
20231 }
20232 run_test 413b "mkdir with balanced space usage"
20233
20234 test_414() {
20235 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20236         $LCTL set_param fail_loc=0x80000521
20237         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20238         rm -f $DIR/$tfile
20239 }
20240 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20241
20242 test_415() {
20243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20244         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20245                 skip "Need server version at least 2.11.52"
20246
20247         # LU-11102
20248         local total
20249         local setattr_pid
20250         local start_time
20251         local end_time
20252         local duration
20253
20254         total=500
20255         # this test may be slow on ZFS
20256         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20257
20258         # though this test is designed for striped directory, let's test normal
20259         # directory too since lock is always saved as CoS lock.
20260         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20261         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20262
20263         (
20264                 while true; do
20265                         touch $DIR/$tdir
20266                 done
20267         ) &
20268         setattr_pid=$!
20269
20270         start_time=$(date +%s)
20271         for i in $(seq $total); do
20272                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20273                         > /dev/null
20274         done
20275         end_time=$(date +%s)
20276         duration=$((end_time - start_time))
20277
20278         kill -9 $setattr_pid
20279
20280         echo "rename $total files took $duration sec"
20281         [ $duration -lt 100 ] || error "rename took $duration sec"
20282 }
20283 run_test 415 "lock revoke is not missing"
20284
20285 test_416() {
20286         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20287                 skip "Need server version at least 2.11.55"
20288
20289         # define OBD_FAIL_OSD_TXN_START    0x19a
20290         do_facet mds1 lctl set_param fail_loc=0x19a
20291
20292         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20293
20294         true
20295 }
20296 run_test 416 "transaction start failure won't cause system hung"
20297
20298 cleanup_417() {
20299         trap 0
20300         do_nodes $(comma_list $(mdts_nodes)) \
20301                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20302         do_nodes $(comma_list $(mdts_nodes)) \
20303                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20304         do_nodes $(comma_list $(mdts_nodes)) \
20305                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20306 }
20307
20308 test_417() {
20309         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20310         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20311                 skip "Need MDS version at least 2.11.56"
20312
20313         trap cleanup_417 RETURN EXIT
20314
20315         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20316         do_nodes $(comma_list $(mdts_nodes)) \
20317                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20318         $LFS migrate -m 0 $DIR/$tdir.1 &&
20319                 error "migrate dir $tdir.1 should fail"
20320
20321         do_nodes $(comma_list $(mdts_nodes)) \
20322                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20323         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20324                 error "create remote dir $tdir.2 should fail"
20325
20326         do_nodes $(comma_list $(mdts_nodes)) \
20327                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20328         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20329                 error "create striped dir $tdir.3 should fail"
20330         true
20331 }
20332 run_test 417 "disable remote dir, striped dir and dir migration"
20333
20334 # Checks that the outputs of df [-i] and lfs df [-i] match
20335 #
20336 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20337 check_lfs_df() {
20338         local dir=$2
20339         local inodes
20340         local df_out
20341         local lfs_df_out
20342         local count
20343         local passed=false
20344
20345         # blocks or inodes
20346         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20347
20348         for count in {1..100}; do
20349                 cancel_lru_locks
20350                 sync; sleep 0.2
20351
20352                 # read the lines of interest
20353                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20354                         error "df $inodes $dir | tail -n +2 failed"
20355                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20356                         error "lfs df $inodes $dir | grep summary: failed"
20357
20358                 # skip first substrings of each output as they are different
20359                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20360                 # compare the two outputs
20361                 passed=true
20362                 for i in {1..5}; do
20363                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20364                 done
20365                 $passed && break
20366         done
20367
20368         if ! $passed; then
20369                 df -P $inodes $dir
20370                 echo
20371                 lfs df $inodes $dir
20372                 error "df and lfs df $1 output mismatch: "      \
20373                       "df ${inodes}: ${df_out[*]}, "            \
20374                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20375         fi
20376 }
20377
20378 test_418() {
20379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20380
20381         local dir=$DIR/$tdir
20382         local numfiles=$((RANDOM % 4096 + 2))
20383         local numblocks=$((RANDOM % 256 + 1))
20384
20385         wait_delete_completed
20386         test_mkdir $dir
20387
20388         # check block output
20389         check_lfs_df blocks $dir
20390         # check inode output
20391         check_lfs_df inodes $dir
20392
20393         # create a single file and retest
20394         echo "Creating a single file and testing"
20395         createmany -o $dir/$tfile- 1 &>/dev/null ||
20396                 error "creating 1 file in $dir failed"
20397         check_lfs_df blocks $dir
20398         check_lfs_df inodes $dir
20399
20400         # create a random number of files
20401         echo "Creating $((numfiles - 1)) files and testing"
20402         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20403                 error "creating $((numfiles - 1)) files in $dir failed"
20404
20405         # write a random number of blocks to the first test file
20406         echo "Writing $numblocks 4K blocks and testing"
20407         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20408                 count=$numblocks &>/dev/null ||
20409                 error "dd to $dir/${tfile}-0 failed"
20410
20411         # retest
20412         check_lfs_df blocks $dir
20413         check_lfs_df inodes $dir
20414
20415         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20416                 error "unlinking $numfiles files in $dir failed"
20417 }
20418 run_test 418 "df and lfs df outputs match"
20419
20420 test_419()
20421 {
20422         local dir=$DIR/$tdir
20423
20424         mkdir -p $dir
20425         touch $dir/file
20426
20427         cancel_lru_locks mdc
20428
20429         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20430         $LCTL set_param fail_loc=0x1410
20431         cat $dir/file
20432         $LCTL set_param fail_loc=0
20433         rm -rf $dir
20434 }
20435 run_test 419 "Verify open file by name doesn't crash kernel"
20436
20437 test_420()
20438 {
20439         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20440                 skip "Need MDS version at least 2.12.53"
20441
20442         local SAVE_UMASK=$(umask)
20443         local dir=$DIR/$tdir
20444         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20445
20446         mkdir -p $dir
20447         umask 0000
20448         mkdir -m03777 $dir/testdir
20449         ls -dn $dir/testdir
20450         # Need to remove trailing '.' when SELinux is enabled
20451         local dirperms=$(ls -dn $dir/testdir |
20452                          awk '{ sub(/\.$/, "", $1); print $1}')
20453         [ $dirperms == "drwxrwsrwt" ] ||
20454                 error "incorrect perms on $dir/testdir"
20455
20456         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20457                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20458         ls -n $dir/testdir/testfile
20459         local fileperms=$(ls -n $dir/testdir/testfile |
20460                           awk '{ sub(/\.$/, "", $1); print $1}')
20461         [ $fileperms == "-rwxr-xr-x" ] ||
20462                 error "incorrect perms on $dir/testdir/testfile"
20463
20464         umask $SAVE_UMASK
20465 }
20466 run_test 420 "clear SGID bit on non-directories for non-members"
20467
20468 test_421a() {
20469         local cnt
20470         local fid1
20471         local fid2
20472
20473         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20474                 skip "Need MDS version at least 2.12.54"
20475
20476         test_mkdir $DIR/$tdir
20477         createmany -o $DIR/$tdir/f 3
20478         cnt=$(ls -1 $DIR/$tdir | wc -l)
20479         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20480
20481         fid1=$(lfs path2fid $DIR/$tdir/f1)
20482         fid2=$(lfs path2fid $DIR/$tdir/f2)
20483         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
20484
20485         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
20486         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
20487
20488         cnt=$(ls -1 $DIR/$tdir | wc -l)
20489         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20490
20491         rm -f $DIR/$tdir/f3 || error "can't remove f3"
20492         createmany -o $DIR/$tdir/f 3
20493         cnt=$(ls -1 $DIR/$tdir | wc -l)
20494         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20495
20496         fid1=$(lfs path2fid $DIR/$tdir/f1)
20497         fid2=$(lfs path2fid $DIR/$tdir/f2)
20498         echo "remove using fsname $FSNAME"
20499         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
20500
20501         cnt=$(ls -1 $DIR/$tdir | wc -l)
20502         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20503 }
20504 run_test 421a "simple rm by fid"
20505
20506 test_421b() {
20507         local cnt
20508         local FID1
20509         local FID2
20510
20511         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20512                 skip "Need MDS version at least 2.12.54"
20513
20514         test_mkdir $DIR/$tdir
20515         createmany -o $DIR/$tdir/f 3
20516         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
20517         MULTIPID=$!
20518
20519         FID1=$(lfs path2fid $DIR/$tdir/f1)
20520         FID2=$(lfs path2fid $DIR/$tdir/f2)
20521         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
20522
20523         kill -USR1 $MULTIPID
20524         wait
20525
20526         cnt=$(ls $DIR/$tdir | wc -l)
20527         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
20528 }
20529 run_test 421b "rm by fid on open file"
20530
20531 test_421c() {
20532         local cnt
20533         local FIDS
20534
20535         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20536                 skip "Need MDS version at least 2.12.54"
20537
20538         test_mkdir $DIR/$tdir
20539         createmany -o $DIR/$tdir/f 3
20540         touch $DIR/$tdir/$tfile
20541         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
20542         cnt=$(ls -1 $DIR/$tdir | wc -l)
20543         [ $cnt != 184 ] && error "unexpected #files: $cnt"
20544
20545         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
20546         $LFS rmfid $DIR $FID1 || error "rmfid failed"
20547
20548         cnt=$(ls $DIR/$tdir | wc -l)
20549         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
20550 }
20551 run_test 421c "rm by fid against hardlinked files"
20552
20553 test_421d() {
20554         local cnt
20555         local FIDS
20556
20557         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20558                 skip "Need MDS version at least 2.12.54"
20559
20560         test_mkdir $DIR/$tdir
20561         createmany -o $DIR/$tdir/f 4097
20562         cnt=$(ls -1 $DIR/$tdir | wc -l)
20563         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
20564
20565         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
20566         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20567
20568         cnt=$(ls $DIR/$tdir | wc -l)
20569         rm -rf $DIR/$tdir
20570         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20571 }
20572 run_test 421d "rmfid en masse"
20573
20574 test_421e() {
20575         local cnt
20576         local FID
20577
20578         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20579         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20580                 skip "Need MDS version at least 2.12.54"
20581
20582         mkdir -p $DIR/$tdir
20583         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20584         createmany -o $DIR/$tdir/striped_dir/f 512
20585         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20586         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20587
20588         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20589                 sed "s/[/][^:]*://g")
20590         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20591
20592         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20593         rm -rf $DIR/$tdir
20594         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20595 }
20596 run_test 421e "rmfid in DNE"
20597
20598 test_421f() {
20599         local cnt
20600         local FID
20601
20602         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20603                 skip "Need MDS version at least 2.12.54"
20604
20605         test_mkdir $DIR/$tdir
20606         touch $DIR/$tdir/f
20607         cnt=$(ls -1 $DIR/$tdir | wc -l)
20608         [ $cnt != 1 ] && error "unexpected #files: $cnt"
20609
20610         FID=$(lfs path2fid $DIR/$tdir/f)
20611         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
20612         # rmfid should fail
20613         cnt=$(ls -1 $DIR/$tdir | wc -l)
20614         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
20615
20616         chmod a+rw $DIR/$tdir
20617         ls -la $DIR/$tdir
20618         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
20619         # rmfid should fail
20620         cnt=$(ls -1 $DIR/$tdir | wc -l)
20621         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
20622
20623         rm -f $DIR/$tdir/f
20624         $RUNAS touch $DIR/$tdir/f
20625         FID=$(lfs path2fid $DIR/$tdir/f)
20626         echo "rmfid as root"
20627         $LFS rmfid $DIR $FID || error "rmfid as root failed"
20628         cnt=$(ls -1 $DIR/$tdir | wc -l)
20629         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
20630
20631         rm -f $DIR/$tdir/f
20632         $RUNAS touch $DIR/$tdir/f
20633         cnt=$(ls -1 $DIR/$tdir | wc -l)
20634         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
20635         FID=$(lfs path2fid $DIR/$tdir/f)
20636         # rmfid w/o user_fid2path mount option should fail
20637         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
20638         cnt=$(ls -1 $DIR/$tdir | wc -l)
20639         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
20640
20641         umount_client $MOUNT || "failed to umount client"
20642         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
20643                 "failed to mount client'"
20644
20645         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
20646         # rmfid should succeed
20647         cnt=$(ls -1 $DIR/$tdir | wc -l)
20648         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
20649
20650         # rmfid shouldn't allow to remove files due to dir's permission
20651         chmod a+rwx $DIR/$tdir
20652         touch $DIR/$tdir/f
20653         ls -la $DIR/$tdir
20654         FID=$(lfs path2fid $DIR/$tdir/f)
20655         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
20656
20657         umount_client $MOUNT || "failed to umount client"
20658         mount_client $MOUNT "$MOUNT_OPTS" ||
20659                 "failed to mount client'"
20660
20661 }
20662 run_test 421f "rmfid checks permissions"
20663
20664 test_421g() {
20665         local cnt
20666         local FIDS
20667
20668         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20669         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20670                 skip "Need MDS version at least 2.12.54"
20671
20672         mkdir -p $DIR/$tdir
20673         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20674         createmany -o $DIR/$tdir/striped_dir/f 512
20675         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20676         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20677
20678         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20679                 sed "s/[/][^:]*://g")
20680
20681         rm -f $DIR/$tdir/striped_dir/f1*
20682         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20683         removed=$((512 - cnt))
20684
20685         # few files have been just removed, so we expect
20686         # rmfid to fail on their fids
20687         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
20688         [ $removed != $errors ] && error "$errors != $removed"
20689
20690         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20691         rm -rf $DIR/$tdir
20692         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20693 }
20694 run_test 421g "rmfid to return errors properly"
20695
20696 prep_801() {
20697         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20698         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20699                 skip "Need server version at least 2.9.55"
20700
20701         start_full_debug_logging
20702 }
20703
20704 post_801() {
20705         stop_full_debug_logging
20706 }
20707
20708 barrier_stat() {
20709         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20710                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20711                            awk '/The barrier for/ { print $7 }')
20712                 echo $st
20713         else
20714                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20715                 echo \'$st\'
20716         fi
20717 }
20718
20719 barrier_expired() {
20720         local expired
20721
20722         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20723                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20724                           awk '/will be expired/ { print $7 }')
20725         else
20726                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20727         fi
20728
20729         echo $expired
20730 }
20731
20732 test_801a() {
20733         prep_801
20734
20735         echo "Start barrier_freeze at: $(date)"
20736         #define OBD_FAIL_BARRIER_DELAY          0x2202
20737         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20738         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20739
20740         sleep 2
20741         local b_status=$(barrier_stat)
20742         echo "Got barrier status at: $(date)"
20743         [ "$b_status" = "'freezing_p1'" ] ||
20744                 error "(1) unexpected barrier status $b_status"
20745
20746         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20747         wait
20748         b_status=$(barrier_stat)
20749         [ "$b_status" = "'frozen'" ] ||
20750                 error "(2) unexpected barrier status $b_status"
20751
20752         local expired=$(barrier_expired)
20753         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20754         sleep $((expired + 3))
20755
20756         b_status=$(barrier_stat)
20757         [ "$b_status" = "'expired'" ] ||
20758                 error "(3) unexpected barrier status $b_status"
20759
20760         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20761                 error "(4) fail to freeze barrier"
20762
20763         b_status=$(barrier_stat)
20764         [ "$b_status" = "'frozen'" ] ||
20765                 error "(5) unexpected barrier status $b_status"
20766
20767         echo "Start barrier_thaw at: $(date)"
20768         #define OBD_FAIL_BARRIER_DELAY          0x2202
20769         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20770         do_facet mgs $LCTL barrier_thaw $FSNAME &
20771
20772         sleep 2
20773         b_status=$(barrier_stat)
20774         echo "Got barrier status at: $(date)"
20775         [ "$b_status" = "'thawing'" ] ||
20776                 error "(6) unexpected barrier status $b_status"
20777
20778         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20779         wait
20780         b_status=$(barrier_stat)
20781         [ "$b_status" = "'thawed'" ] ||
20782                 error "(7) unexpected barrier status $b_status"
20783
20784         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20785         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20786         do_facet mgs $LCTL barrier_freeze $FSNAME
20787
20788         b_status=$(barrier_stat)
20789         [ "$b_status" = "'failed'" ] ||
20790                 error "(8) unexpected barrier status $b_status"
20791
20792         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20793         do_facet mgs $LCTL barrier_thaw $FSNAME
20794
20795         post_801
20796 }
20797 run_test 801a "write barrier user interfaces and stat machine"
20798
20799 test_801b() {
20800         prep_801
20801
20802         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20803         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20804         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20805         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20806         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20807
20808         cancel_lru_locks mdc
20809
20810         # 180 seconds should be long enough
20811         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20812
20813         local b_status=$(barrier_stat)
20814         [ "$b_status" = "'frozen'" ] ||
20815                 error "(6) unexpected barrier status $b_status"
20816
20817         mkdir $DIR/$tdir/d0/d10 &
20818         mkdir_pid=$!
20819
20820         touch $DIR/$tdir/d1/f13 &
20821         touch_pid=$!
20822
20823         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20824         ln_pid=$!
20825
20826         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20827         mv_pid=$!
20828
20829         rm -f $DIR/$tdir/d4/f12 &
20830         rm_pid=$!
20831
20832         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20833
20834         # To guarantee taht the 'stat' is not blocked
20835         b_status=$(barrier_stat)
20836         [ "$b_status" = "'frozen'" ] ||
20837                 error "(8) unexpected barrier status $b_status"
20838
20839         # let above commands to run at background
20840         sleep 5
20841
20842         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20843         ps -p $touch_pid || error "(10) touch should be blocked"
20844         ps -p $ln_pid || error "(11) link should be blocked"
20845         ps -p $mv_pid || error "(12) rename should be blocked"
20846         ps -p $rm_pid || error "(13) unlink should be blocked"
20847
20848         b_status=$(barrier_stat)
20849         [ "$b_status" = "'frozen'" ] ||
20850                 error "(14) unexpected barrier status $b_status"
20851
20852         do_facet mgs $LCTL barrier_thaw $FSNAME
20853         b_status=$(barrier_stat)
20854         [ "$b_status" = "'thawed'" ] ||
20855                 error "(15) unexpected barrier status $b_status"
20856
20857         wait $mkdir_pid || error "(16) mkdir should succeed"
20858         wait $touch_pid || error "(17) touch should succeed"
20859         wait $ln_pid || error "(18) link should succeed"
20860         wait $mv_pid || error "(19) rename should succeed"
20861         wait $rm_pid || error "(20) unlink should succeed"
20862
20863         post_801
20864 }
20865 run_test 801b "modification will be blocked by write barrier"
20866
20867 test_801c() {
20868         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20869
20870         prep_801
20871
20872         stop mds2 || error "(1) Fail to stop mds2"
20873
20874         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20875
20876         local b_status=$(barrier_stat)
20877         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20878                 do_facet mgs $LCTL barrier_thaw $FSNAME
20879                 error "(2) unexpected barrier status $b_status"
20880         }
20881
20882         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20883                 error "(3) Fail to rescan barrier bitmap"
20884
20885         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20886
20887         b_status=$(barrier_stat)
20888         [ "$b_status" = "'frozen'" ] ||
20889                 error "(4) unexpected barrier status $b_status"
20890
20891         do_facet mgs $LCTL barrier_thaw $FSNAME
20892         b_status=$(barrier_stat)
20893         [ "$b_status" = "'thawed'" ] ||
20894                 error "(5) unexpected barrier status $b_status"
20895
20896         local devname=$(mdsdevname 2)
20897
20898         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20899
20900         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20901                 error "(7) Fail to rescan barrier bitmap"
20902
20903         post_801
20904 }
20905 run_test 801c "rescan barrier bitmap"
20906
20907 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20908 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20909 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20910 saved_MOUNT_OPTS=$MOUNT_OPTS
20911
20912 cleanup_802a() {
20913         trap 0
20914
20915         stopall
20916         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20917         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20918         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20919         MOUNT_OPTS=$saved_MOUNT_OPTS
20920         setupall
20921 }
20922
20923 test_802a() {
20924
20925         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20926         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20927                 skip "Need server version at least 2.9.55"
20928
20929         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20930
20931         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20932
20933         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20934                 error "(2) Fail to copy"
20935
20936         trap cleanup_802a EXIT
20937
20938         # sync by force before remount as readonly
20939         sync; sync_all_data; sleep 3; sync_all_data
20940
20941         stopall
20942
20943         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20944         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20945         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20946
20947         echo "Mount the server as read only"
20948         setupall server_only || error "(3) Fail to start servers"
20949
20950         echo "Mount client without ro should fail"
20951         mount_client $MOUNT &&
20952                 error "(4) Mount client without 'ro' should fail"
20953
20954         echo "Mount client with ro should succeed"
20955         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
20956         mount_client $MOUNT ||
20957                 error "(5) Mount client with 'ro' should succeed"
20958
20959         echo "Modify should be refused"
20960         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20961
20962         echo "Read should be allowed"
20963         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20964                 error "(7) Read should succeed under ro mode"
20965
20966         cleanup_802a
20967 }
20968 run_test 802a "simulate readonly device"
20969
20970 test_802b() {
20971         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20972         remote_mds_nodsh && skip "remote MDS with nodsh"
20973
20974         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20975                 skip "readonly option not available"
20976
20977         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20978
20979         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20980                 error "(2) Fail to copy"
20981
20982         # write back all cached data before setting MDT to readonly
20983         cancel_lru_locks
20984         sync_all_data
20985
20986         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20987         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20988
20989         echo "Modify should be refused"
20990         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20991
20992         echo "Read should be allowed"
20993         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20994                 error "(7) Read should succeed under ro mode"
20995
20996         # disable readonly
20997         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20998 }
20999 run_test 802b "be able to set MDTs to readonly"
21000
21001 test_803() {
21002         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21003         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21004                 skip "MDS needs to be newer than 2.10.54"
21005
21006         mkdir -p $DIR/$tdir
21007         # Create some objects on all MDTs to trigger related logs objects
21008         for idx in $(seq $MDSCOUNT); do
21009                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21010                         $DIR/$tdir/dir${idx} ||
21011                         error "Fail to create $DIR/$tdir/dir${idx}"
21012         done
21013
21014         sync; sleep 3
21015         wait_delete_completed # ensure old test cleanups are finished
21016         echo "before create:"
21017         $LFS df -i $MOUNT
21018         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21019
21020         for i in {1..10}; do
21021                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21022                         error "Fail to create $DIR/$tdir/foo$i"
21023         done
21024
21025         sync; sleep 3
21026         echo "after create:"
21027         $LFS df -i $MOUNT
21028         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21029
21030         # allow for an llog to be cleaned up during the test
21031         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21032                 error "before ($before_used) + 10 > after ($after_used)"
21033
21034         for i in {1..10}; do
21035                 rm -rf $DIR/$tdir/foo$i ||
21036                         error "Fail to remove $DIR/$tdir/foo$i"
21037         done
21038
21039         sleep 3 # avoid MDT return cached statfs
21040         wait_delete_completed
21041         echo "after unlink:"
21042         $LFS df -i $MOUNT
21043         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21044
21045         # allow for an llog to be created during the test
21046         [ $after_used -le $((before_used + 1)) ] ||
21047                 error "after ($after_used) > before ($before_used) + 1"
21048 }
21049 run_test 803 "verify agent object for remote object"
21050
21051 test_804() {
21052         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21053         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21054                 skip "MDS needs to be newer than 2.10.54"
21055         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21056
21057         mkdir -p $DIR/$tdir
21058         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21059                 error "Fail to create $DIR/$tdir/dir0"
21060
21061         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21062         local dev=$(mdsdevname 2)
21063
21064         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21065                 grep ${fid} || error "NOT found agent entry for dir0"
21066
21067         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21068                 error "Fail to create $DIR/$tdir/dir1"
21069
21070         touch $DIR/$tdir/dir1/foo0 ||
21071                 error "Fail to create $DIR/$tdir/dir1/foo0"
21072         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21073         local rc=0
21074
21075         for idx in $(seq $MDSCOUNT); do
21076                 dev=$(mdsdevname $idx)
21077                 do_facet mds${idx} \
21078                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21079                         grep ${fid} && rc=$idx
21080         done
21081
21082         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21083                 error "Fail to rename foo0 to foo1"
21084         if [ $rc -eq 0 ]; then
21085                 for idx in $(seq $MDSCOUNT); do
21086                         dev=$(mdsdevname $idx)
21087                         do_facet mds${idx} \
21088                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21089                         grep ${fid} && rc=$idx
21090                 done
21091         fi
21092
21093         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21094                 error "Fail to rename foo1 to foo2"
21095         if [ $rc -eq 0 ]; then
21096                 for idx in $(seq $MDSCOUNT); do
21097                         dev=$(mdsdevname $idx)
21098                         do_facet mds${idx} \
21099                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21100                         grep ${fid} && rc=$idx
21101                 done
21102         fi
21103
21104         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21105
21106         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21107                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21108         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21109                 error "Fail to rename foo2 to foo0"
21110         unlink $DIR/$tdir/dir1/foo0 ||
21111                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21112         rm -rf $DIR/$tdir/dir0 ||
21113                 error "Fail to rm $DIR/$tdir/dir0"
21114
21115         for idx in $(seq $MDSCOUNT); do
21116                 dev=$(mdsdevname $idx)
21117                 rc=0
21118
21119                 stop mds${idx}
21120                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21121                         rc=$?
21122                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21123                         error "mount mds$idx failed"
21124                 df $MOUNT > /dev/null 2>&1
21125
21126                 # e2fsck should not return error
21127                 [ $rc -eq 0 ] ||
21128                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21129         done
21130 }
21131 run_test 804 "verify agent entry for remote entry"
21132
21133 cleanup_805() {
21134         do_facet $SINGLEMDS zfs set quota=$old $fsset
21135         unlinkmany $DIR/$tdir/f- 1000000
21136         trap 0
21137 }
21138
21139 test_805() {
21140         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21141         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21142         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21143                 skip "netfree not implemented before 0.7"
21144         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21145                 skip "Need MDS version at least 2.10.57"
21146
21147         local fsset
21148         local freekb
21149         local usedkb
21150         local old
21151         local quota
21152         local pref="osd-zfs.lustre-MDT0000."
21153
21154         # limit available space on MDS dataset to meet nospace issue
21155         # quickly. then ZFS 0.7.2 can use reserved space if asked
21156         # properly (using netfree flag in osd_declare_destroy()
21157         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21158         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21159                 gawk '{print $3}')
21160         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21161         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21162         let "usedkb=usedkb-freekb"
21163         let "freekb=freekb/2"
21164         if let "freekb > 5000"; then
21165                 let "freekb=5000"
21166         fi
21167         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21168         trap cleanup_805 EXIT
21169         mkdir $DIR/$tdir
21170         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21171         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21172         rm -rf $DIR/$tdir || error "not able to remove"
21173         do_facet $SINGLEMDS zfs set quota=$old $fsset
21174         trap 0
21175 }
21176 run_test 805 "ZFS can remove from full fs"
21177
21178 # Size-on-MDS test
21179 check_lsom_data()
21180 {
21181         local file=$1
21182         local size=$($LFS getsom -s $file)
21183         local expect=$(stat -c %s $file)
21184
21185         [[ $size == $expect ]] ||
21186                 error "$file expected size: $expect, got: $size"
21187
21188         local blocks=$($LFS getsom -b $file)
21189         expect=$(stat -c %b $file)
21190         [[ $blocks == $expect ]] ||
21191                 error "$file expected blocks: $expect, got: $blocks"
21192 }
21193
21194 check_lsom_size()
21195 {
21196         local size=$($LFS getsom -s $1)
21197         local expect=$2
21198
21199         [[ $size == $expect ]] ||
21200                 error "$file expected size: $expect, got: $size"
21201 }
21202
21203 test_806() {
21204         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21205                 skip "Need MDS version at least 2.11.52"
21206
21207         local bs=1048576
21208
21209         touch $DIR/$tfile || error "touch $tfile failed"
21210
21211         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21212         save_lustre_params client "llite.*.xattr_cache" > $save
21213         lctl set_param llite.*.xattr_cache=0
21214         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21215
21216         # single-threaded write
21217         echo "Test SOM for single-threaded write"
21218         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21219                 error "write $tfile failed"
21220         check_lsom_size $DIR/$tfile $bs
21221
21222         local num=32
21223         local size=$(($num * $bs))
21224         local offset=0
21225         local i
21226
21227         echo "Test SOM for single client multi-threaded($num) write"
21228         $TRUNCATE $DIR/$tfile 0
21229         for ((i = 0; i < $num; i++)); do
21230                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21231                 local pids[$i]=$!
21232                 offset=$((offset + $bs))
21233         done
21234         for (( i=0; i < $num; i++ )); do
21235                 wait ${pids[$i]}
21236         done
21237         check_lsom_size $DIR/$tfile $size
21238
21239         $TRUNCATE $DIR/$tfile 0
21240         for ((i = 0; i < $num; i++)); do
21241                 offset=$((offset - $bs))
21242                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21243                 local pids[$i]=$!
21244         done
21245         for (( i=0; i < $num; i++ )); do
21246                 wait ${pids[$i]}
21247         done
21248         check_lsom_size $DIR/$tfile $size
21249
21250         # multi-client wirtes
21251         num=$(get_node_count ${CLIENTS//,/ })
21252         size=$(($num * $bs))
21253         offset=0
21254         i=0
21255
21256         echo "Test SOM for multi-client ($num) writes"
21257         $TRUNCATE $DIR/$tfile 0
21258         for client in ${CLIENTS//,/ }; do
21259                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21260                 local pids[$i]=$!
21261                 i=$((i + 1))
21262                 offset=$((offset + $bs))
21263         done
21264         for (( i=0; i < $num; i++ )); do
21265                 wait ${pids[$i]}
21266         done
21267         check_lsom_size $DIR/$tfile $offset
21268
21269         i=0
21270         $TRUNCATE $DIR/$tfile 0
21271         for client in ${CLIENTS//,/ }; do
21272                 offset=$((offset - $bs))
21273                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21274                 local pids[$i]=$!
21275                 i=$((i + 1))
21276         done
21277         for (( i=0; i < $num; i++ )); do
21278                 wait ${pids[$i]}
21279         done
21280         check_lsom_size $DIR/$tfile $size
21281
21282         # verify truncate
21283         echo "Test SOM for truncate"
21284         $TRUNCATE $DIR/$tfile 1048576
21285         check_lsom_size $DIR/$tfile 1048576
21286         $TRUNCATE $DIR/$tfile 1234
21287         check_lsom_size $DIR/$tfile 1234
21288
21289         # verify SOM blocks count
21290         echo "Verify SOM block count"
21291         $TRUNCATE $DIR/$tfile 0
21292         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21293                 error "failed to write file $tfile"
21294         check_lsom_data $DIR/$tfile
21295 }
21296 run_test 806 "Verify Lazy Size on MDS"
21297
21298 test_807() {
21299         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21300         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21301                 skip "Need MDS version at least 2.11.52"
21302
21303         # Registration step
21304         changelog_register || error "changelog_register failed"
21305         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21306         changelog_users $SINGLEMDS | grep -q $cl_user ||
21307                 error "User $cl_user not found in changelog_users"
21308
21309         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21310         save_lustre_params client "llite.*.xattr_cache" > $save
21311         lctl set_param llite.*.xattr_cache=0
21312         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21313
21314         rm -rf $DIR/$tdir || error "rm $tdir failed"
21315         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21316         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21317         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21318         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21319                 error "truncate $tdir/trunc failed"
21320
21321         local bs=1048576
21322         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21323                 error "write $tfile failed"
21324
21325         # multi-client wirtes
21326         local num=$(get_node_count ${CLIENTS//,/ })
21327         local offset=0
21328         local i=0
21329
21330         echo "Test SOM for multi-client ($num) writes"
21331         touch $DIR/$tfile || error "touch $tfile failed"
21332         $TRUNCATE $DIR/$tfile 0
21333         for client in ${CLIENTS//,/ }; do
21334                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21335                 local pids[$i]=$!
21336                 i=$((i + 1))
21337                 offset=$((offset + $bs))
21338         done
21339         for (( i=0; i < $num; i++ )); do
21340                 wait ${pids[$i]}
21341         done
21342
21343         sleep 5
21344         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21345         check_lsom_data $DIR/$tdir/trunc
21346         check_lsom_data $DIR/$tdir/single_dd
21347         check_lsom_data $DIR/$tfile
21348
21349         rm -rf $DIR/$tdir
21350         # Deregistration step
21351         changelog_deregister || error "changelog_deregister failed"
21352 }
21353 run_test 807 "verify LSOM syncing tool"
21354
21355 check_som_nologged()
21356 {
21357         local lines=$($LFS changelog $FSNAME-MDT0000 |
21358                 grep 'x=trusted.som' | wc -l)
21359         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21360 }
21361
21362 test_808() {
21363         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21364                 skip "Need MDS version at least 2.11.55"
21365
21366         # Registration step
21367         changelog_register || error "changelog_register failed"
21368
21369         touch $DIR/$tfile || error "touch $tfile failed"
21370         check_som_nologged
21371
21372         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21373                 error "write $tfile failed"
21374         check_som_nologged
21375
21376         $TRUNCATE $DIR/$tfile 1234
21377         check_som_nologged
21378
21379         $TRUNCATE $DIR/$tfile 1048576
21380         check_som_nologged
21381
21382         # Deregistration step
21383         changelog_deregister || error "changelog_deregister failed"
21384 }
21385 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21386
21387 check_som_nodata()
21388 {
21389         $LFS getsom $1
21390         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21391 }
21392
21393 test_809() {
21394         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21395                 skip "Need MDS version at least 2.11.56"
21396
21397         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21398                 error "failed to create DoM-only file $DIR/$tfile"
21399         touch $DIR/$tfile || error "touch $tfile failed"
21400         check_som_nodata $DIR/$tfile
21401
21402         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21403                 error "write $tfile failed"
21404         check_som_nodata $DIR/$tfile
21405
21406         $TRUNCATE $DIR/$tfile 1234
21407         check_som_nodata $DIR/$tfile
21408
21409         $TRUNCATE $DIR/$tfile 4097
21410         check_som_nodata $DIR/$file
21411 }
21412 run_test 809 "Verify no SOM xattr store for DoM-only files"
21413
21414 test_810() {
21415         local ORIG
21416         local CSUM
21417
21418         # t10 seem to dislike partial pages
21419         lctl set_param osc.*.checksum_type=adler
21420         lctl set_param fail_loc=0x411
21421         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21422         ORIG=$(md5sum $DIR/$tfile)
21423         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21424         CSUM=$(md5sum $DIR/$tfile)
21425         set_checksum_type adler
21426         if [ "$ORIG" != "$CSUM" ]; then
21427                 error "$ORIG != $CSUM"
21428         fi
21429 }
21430 run_test 810 "partial page writes on ZFS (LU-11663)"
21431
21432 test_811() {
21433         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21434                 skip "Need MDS version at least 2.11.56"
21435
21436         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21437         do_facet mds1 $LCTL set_param fail_loc=0x165
21438         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21439
21440         stop mds1
21441         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21442
21443         sleep 5
21444         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21445                 error "MDD orphan cleanup thread not quit"
21446 }
21447 run_test 811 "orphan name stub can be cleaned up in startup"
21448
21449 test_812() {
21450         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21451                 skip "OST < 2.12.51 doesn't support this fail_loc"
21452         [ "$SHARED_KEY" = true ] &&
21453                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21454
21455         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21456         # ensure ost1 is connected
21457         stat $DIR/$tfile >/dev/null || error "can't stat"
21458         wait_osc_import_state client ost1 FULL
21459         # no locks, no reqs to let the connection idle
21460         cancel_lru_locks osc
21461
21462         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21463 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21464         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21465         wait_osc_import_state client ost1 CONNECTING
21466         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21467
21468         stat $DIR/$tfile >/dev/null || error "can't stat file"
21469 }
21470 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21471
21472 test_813() {
21473         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21474         [ -z "$file_heat_sav" ] && skip "no file heat support"
21475
21476         local readsample
21477         local writesample
21478         local readbyte
21479         local writebyte
21480         local readsample1
21481         local writesample1
21482         local readbyte1
21483         local writebyte1
21484
21485         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21486         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21487
21488         $LCTL set_param -n llite.*.file_heat=1
21489         echo "Turn on file heat"
21490         echo "Period second: $period_second, Decay percentage: $decay_pct"
21491
21492         echo "QQQQ" > $DIR/$tfile
21493         echo "QQQQ" > $DIR/$tfile
21494         echo "QQQQ" > $DIR/$tfile
21495         cat $DIR/$tfile > /dev/null
21496         cat $DIR/$tfile > /dev/null
21497         cat $DIR/$tfile > /dev/null
21498         cat $DIR/$tfile > /dev/null
21499
21500         local out=$($LFS heat_get $DIR/$tfile)
21501
21502         $LFS heat_get $DIR/$tfile
21503         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21504         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21505         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21506         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21507
21508         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21509         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21510         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21511         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21512
21513         sleep $((period_second + 3))
21514         echo "Sleep $((period_second + 3)) seconds..."
21515         # The recursion formula to calculate the heat of the file f is as
21516         # follow:
21517         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21518         # Where Hi is the heat value in the period between time points i*I and
21519         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21520         # to the weight of Ci.
21521         out=$($LFS heat_get $DIR/$tfile)
21522         $LFS heat_get $DIR/$tfile
21523         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21524         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21525         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21526         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21527
21528         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21529                 error "read sample ($readsample) is wrong"
21530         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21531                 error "write sample ($writesample) is wrong"
21532         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21533                 error "read bytes ($readbyte) is wrong"
21534         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21535                 error "write bytes ($writebyte) is wrong"
21536
21537         echo "QQQQ" > $DIR/$tfile
21538         echo "QQQQ" > $DIR/$tfile
21539         echo "QQQQ" > $DIR/$tfile
21540         cat $DIR/$tfile > /dev/null
21541         cat $DIR/$tfile > /dev/null
21542         cat $DIR/$tfile > /dev/null
21543         cat $DIR/$tfile > /dev/null
21544
21545         sleep $((period_second + 3))
21546         echo "Sleep $((period_second + 3)) seconds..."
21547
21548         out=$($LFS heat_get $DIR/$tfile)
21549         $LFS heat_get $DIR/$tfile
21550         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21551         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21552         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21553         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21554
21555         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21556                 4 * $decay_pct) / 100") -eq 1 ] ||
21557                 error "read sample ($readsample1) is wrong"
21558         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21559                 3 * $decay_pct) / 100") -eq 1 ] ||
21560                 error "write sample ($writesample1) is wrong"
21561         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21562                 20 * $decay_pct) / 100") -eq 1 ] ||
21563                 error "read bytes ($readbyte1) is wrong"
21564         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21565                 15 * $decay_pct) / 100") -eq 1 ] ||
21566                 error "write bytes ($writebyte1) is wrong"
21567
21568         echo "Turn off file heat for the file $DIR/$tfile"
21569         $LFS heat_set -o $DIR/$tfile
21570
21571         echo "QQQQ" > $DIR/$tfile
21572         echo "QQQQ" > $DIR/$tfile
21573         echo "QQQQ" > $DIR/$tfile
21574         cat $DIR/$tfile > /dev/null
21575         cat $DIR/$tfile > /dev/null
21576         cat $DIR/$tfile > /dev/null
21577         cat $DIR/$tfile > /dev/null
21578
21579         out=$($LFS heat_get $DIR/$tfile)
21580         $LFS heat_get $DIR/$tfile
21581         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21582         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21583         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21584         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21585
21586         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21587         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21588         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21589         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21590
21591         echo "Trun on file heat for the file $DIR/$tfile"
21592         $LFS heat_set -O $DIR/$tfile
21593
21594         echo "QQQQ" > $DIR/$tfile
21595         echo "QQQQ" > $DIR/$tfile
21596         echo "QQQQ" > $DIR/$tfile
21597         cat $DIR/$tfile > /dev/null
21598         cat $DIR/$tfile > /dev/null
21599         cat $DIR/$tfile > /dev/null
21600         cat $DIR/$tfile > /dev/null
21601
21602         out=$($LFS heat_get $DIR/$tfile)
21603         $LFS heat_get $DIR/$tfile
21604         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21605         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21606         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21607         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21608
21609         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21610         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21611         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21612         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21613
21614         $LFS heat_set -c $DIR/$tfile
21615         $LCTL set_param -n llite.*.file_heat=0
21616         echo "Turn off file heat support for the Lustre filesystem"
21617
21618         echo "QQQQ" > $DIR/$tfile
21619         echo "QQQQ" > $DIR/$tfile
21620         echo "QQQQ" > $DIR/$tfile
21621         cat $DIR/$tfile > /dev/null
21622         cat $DIR/$tfile > /dev/null
21623         cat $DIR/$tfile > /dev/null
21624         cat $DIR/$tfile > /dev/null
21625
21626         out=$($LFS heat_get $DIR/$tfile)
21627         $LFS heat_get $DIR/$tfile
21628         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21629         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21630         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21631         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21632
21633         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21634         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21635         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21636         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21637
21638         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21639         rm -f $DIR/$tfile
21640 }
21641 run_test 813 "File heat verfication"
21642
21643 test_814()
21644 {
21645         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21646         echo -n y >> $DIR/$tfile
21647         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21648         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21649 }
21650 run_test 814 "sparse cp works as expected (LU-12361)"
21651
21652 test_815()
21653 {
21654         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21655         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21656 }
21657 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21658
21659 test_816() {
21660         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21661         # ensure ost1 is connected
21662         stat $DIR/$tfile >/dev/null || error "can't stat"
21663         wait_osc_import_state client ost1 FULL
21664         # no locks, no reqs to let the connection idle
21665         cancel_lru_locks osc
21666         lru_resize_disable osc
21667         local before
21668         local now
21669         before=$($LCTL get_param -n \
21670                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21671
21672         wait_osc_import_state client ost1 IDLE
21673         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21674         now=$($LCTL get_param -n \
21675               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21676         [ $before == $now ] || error "lru_size changed $before != $now"
21677 }
21678 run_test 816 "do not reset lru_resize on idle reconnect"
21679
21680 cleanup_817() {
21681         umount $tmpdir
21682         exportfs -u localhost:$DIR/nfsexp
21683         rm -rf $DIR/nfsexp
21684 }
21685
21686 test_817() {
21687         systemctl restart nfs-server.service || skip "failed to restart nfsd"
21688
21689         mkdir -p $DIR/nfsexp
21690         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
21691                 error "failed to export nfs"
21692
21693         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
21694         stack_trap cleanup_817 EXIT
21695
21696         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
21697                 error "failed to mount nfs to $tmpdir"
21698
21699         cp /bin/true $tmpdir
21700         $DIR/nfsexp/true || error "failed to execute 'true' command"
21701 }
21702 run_test 817 "nfsd won't cache write lock for exec file"
21703
21704 #
21705 # tests that do cleanup/setup should be run at the end
21706 #
21707
21708 test_900() {
21709         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21710         local ls
21711
21712         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21713         $LCTL set_param fail_loc=0x903
21714
21715         cancel_lru_locks MGC
21716
21717         FAIL_ON_ERROR=true cleanup
21718         FAIL_ON_ERROR=true setup
21719 }
21720 run_test 900 "umount should not race with any mgc requeue thread"
21721
21722 complete $SECONDS
21723 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21724 check_and_cleanup_lustre
21725 if [ "$I_MOUNTED" != "yes" ]; then
21726         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21727 fi
21728 exit_status