Whamcloud - gitweb
LU-10070 tests: New test-framework functionality
[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
57         ALWAYS_EXCEPT+=" 45       103a      317      810"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test: LU-1957
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # 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         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2476           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2477                 skip27D+=" -s 32,33"
2478         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2479                 error "llapi_layout_test failed"
2480
2481         destroy_test_pools || error "destroy test pools failed"
2482
2483         if ! combined_mgs_mds ; then
2484                 umount_mgs_client
2485         fi
2486 }
2487 run_test 27D "validate llapi_layout API"
2488
2489 # Verify that default_easize is increased from its initial value after
2490 # accessing a widely striped file.
2491 test_27E() {
2492         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2493         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2494                 skip "client does not have LU-3338 fix"
2495
2496         # 72 bytes is the minimum space required to store striping
2497         # information for a file striped across one OST:
2498         # (sizeof(struct lov_user_md_v3) +
2499         #  sizeof(struct lov_user_ost_data_v1))
2500         local min_easize=72
2501         $LCTL set_param -n llite.*.default_easize $min_easize ||
2502                 error "lctl set_param failed"
2503         local easize=$($LCTL get_param -n llite.*.default_easize)
2504
2505         [ $easize -eq $min_easize ] ||
2506                 error "failed to set default_easize"
2507
2508         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2509                 error "setstripe failed"
2510         # In order to ensure stat() call actually talks to MDS we need to
2511         # do something drastic to this file to shake off all lock, e.g.
2512         # rename it (kills lookup lock forcing cache cleaning)
2513         mv $DIR/$tfile $DIR/${tfile}-1
2514         ls -l $DIR/${tfile}-1
2515         rm $DIR/${tfile}-1
2516
2517         easize=$($LCTL get_param -n llite.*.default_easize)
2518
2519         [ $easize -gt $min_easize ] ||
2520                 error "default_easize not updated"
2521 }
2522 run_test 27E "check that default extended attribute size properly increases"
2523
2524 test_27F() { # LU-5346/LU-7975
2525         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2526         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2527         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2528                 skip "Need MDS version at least 2.8.51"
2529         remote_ost_nodsh && skip "remote OST with nodsh"
2530
2531         test_mkdir $DIR/$tdir
2532         rm -f $DIR/$tdir/f0
2533         $LFS setstripe -c 2 $DIR/$tdir
2534
2535         # stop all OSTs to reproduce situation for LU-7975 ticket
2536         for num in $(seq $OSTCOUNT); do
2537                 stop ost$num
2538         done
2539
2540         # open/create f0 with O_LOV_DELAY_CREATE
2541         # truncate f0 to a non-0 size
2542         # close
2543         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2544
2545         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2546         # open/write it again to force delayed layout creation
2547         cat /etc/hosts > $DIR/$tdir/f0 &
2548         catpid=$!
2549
2550         # restart OSTs
2551         for num in $(seq $OSTCOUNT); do
2552                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2553                         error "ost$num failed to start"
2554         done
2555
2556         wait $catpid || error "cat failed"
2557
2558         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2559         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2560                 error "wrong stripecount"
2561
2562 }
2563 run_test 27F "Client resend delayed layout creation with non-zero size"
2564
2565 test_27G() { #LU-10629
2566         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2567                 skip "Need MDS version at least 2.11.51"
2568         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2569         remote_mds_nodsh && skip "remote MDS with nodsh"
2570         local POOL=${POOL:-testpool}
2571         local ostrange="0 0 1"
2572
2573         test_mkdir $DIR/$tdir
2574         pool_add $POOL || error "pool_add failed"
2575         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2576         $LFS setstripe -p $POOL $DIR/$tdir
2577
2578         local pool=$($LFS getstripe -p $DIR/$tdir)
2579
2580         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2581
2582         $LFS setstripe -d $DIR/$tdir
2583
2584         pool=$($LFS getstripe -p $DIR/$tdir)
2585
2586         rmdir $DIR/$tdir
2587
2588         [ -z "$pool" ] || error "'$pool' is not empty"
2589 }
2590 run_test 27G "Clear OST pool from stripe"
2591
2592 test_27H() {
2593         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2594                 skip "Need MDS version newer than 2.11.54"
2595         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2596         test_mkdir $DIR/$tdir
2597         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2598         touch $DIR/$tdir/$tfile
2599         $LFS getstripe -c $DIR/$tdir/$tfile
2600         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2601                 error "two-stripe file doesn't have two stripes"
2602
2603         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2604         $LFS getstripe -y $DIR/$tdir/$tfile
2605         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2606              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2607                 error "expected l_ost_idx: [02]$ not matched"
2608
2609         # make sure ost list has been cleared
2610         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2611         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2612                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2613         touch $DIR/$tdir/f3
2614         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2615 }
2616 run_test 27H "Set specific OSTs stripe"
2617
2618 test_27I() {
2619         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2620         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2621         local pool=$TESTNAME
2622         local ostrange="1 1 1"
2623
2624         save_layout_restore_at_exit $MOUNT
2625         $LFS setstripe -c 2 -i 0 $MOUNT
2626         pool_add $pool || error "pool_add failed"
2627         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2628         test_mkdir $DIR/$tdir
2629         $LFS setstripe -p $pool $DIR/$tdir
2630         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2631         $LFS getstripe $DIR/$tdir/$tfile
2632 }
2633 run_test 27I "check that root dir striping does not break parent dir one"
2634
2635 test_27J() {
2636         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2637                 skip "Need MDS version newer than 2.12.51"
2638
2639         test_mkdir $DIR/$tdir
2640         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2641         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2642
2643         # create foreign file (raw way)
2644         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2645                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2646
2647         # verify foreign file (raw way)
2648         parse_foreign_file -f $DIR/$tdir/$tfile |
2649                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2650                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2651         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2653         parse_foreign_file -f $DIR/$tdir/$tfile |
2654                 grep "lov_foreign_size: 73" ||
2655                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2656         parse_foreign_file -f $DIR/$tdir/$tfile |
2657                 grep "lov_foreign_type: 1" ||
2658                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2659         parse_foreign_file -f $DIR/$tdir/$tfile |
2660                 grep "lov_foreign_flags: 0x0000DA08" ||
2661                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2662         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2663                 grep "lov_foreign_value: 0x" |
2664                 sed -e 's/lov_foreign_value: 0x//')
2665         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2666         [[ $lov = ${lov2// /} ]] ||
2667                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2668
2669         # create foreign file (lfs + API)
2670         $LFS setstripe --foreign=daos --flags 0xda08 \
2671                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2672                 error "$DIR/$tdir/${tfile}2: create failed"
2673
2674         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2675                 grep "lfm_magic:.*0x0BD70BD0" ||
2676                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2677         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2678         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2679                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2683                 grep "lfm_flags:.*0x0000DA08" ||
2684                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2685         $LFS getstripe $DIR/$tdir/${tfile}2 |
2686                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2687                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2688
2689         # modify striping should fail
2690         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2691                 error "$DIR/$tdir/$tfile: setstripe should fail"
2692         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2693                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2694
2695         # R/W should fail
2696         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2697         cat $DIR/$tdir/${tfile}2 &&
2698                 error "$DIR/$tdir/${tfile}2: read should fail"
2699         cat /etc/passwd > $DIR/$tdir/$tfile &&
2700                 error "$DIR/$tdir/$tfile: write should fail"
2701         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2702                 error "$DIR/$tdir/${tfile}2: write should fail"
2703
2704         # chmod should work
2705         chmod 222 $DIR/$tdir/$tfile ||
2706                 error "$DIR/$tdir/$tfile: chmod failed"
2707         chmod 222 $DIR/$tdir/${tfile}2 ||
2708                 error "$DIR/$tdir/${tfile}2: chmod failed"
2709
2710         # chown should work
2711         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2712                 error "$DIR/$tdir/$tfile: chown failed"
2713         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2714                 error "$DIR/$tdir/${tfile}2: chown failed"
2715
2716         # rename should work
2717         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2718                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2719         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2720                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2721
2722         #remove foreign file
2723         rm $DIR/$tdir/${tfile}.new ||
2724                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2725         rm $DIR/$tdir/${tfile}2.new ||
2726                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2727 }
2728 run_test 27J "basic ops on file with foreign LOV"
2729
2730 test_27K() {
2731         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2732                 skip "Need MDS version newer than 2.12.49"
2733
2734         test_mkdir $DIR/$tdir
2735         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2736         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2737
2738         # create foreign dir (raw way)
2739         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2740                 error "create_foreign_dir FAILED"
2741
2742         # verify foreign dir (raw way)
2743         parse_foreign_dir -d $DIR/$tdir/$tdir |
2744                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2745                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2746         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2747                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2748         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2749                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2750         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2751                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2752         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2753                 grep "lmv_foreign_value: 0x" |
2754                 sed 's/lmv_foreign_value: 0x//')
2755         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2756                 sed 's/ //g')
2757         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2758
2759         # create foreign dir (lfs + API)
2760         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2761                 $DIR/$tdir/${tdir}2 ||
2762                 error "$DIR/$tdir/${tdir}2: create failed"
2763
2764         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2765                 grep "lfm_magic:.*0x0CD50CD0" ||
2766                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2767         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2768         # - sizeof(lfm_type) - sizeof(lfm_flags)
2769         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2770                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2771         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2774                 grep "lfm_flags:.*0x0000DA05" ||
2775                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2776         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2777                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2778                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2779
2780         # file create in dir should fail
2781         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2782         touch $DIR/$tdir/${tdir}2/$tfile &&
2783                 "$DIR/${tdir}2: file create should fail"
2784
2785         # chmod should work
2786         chmod 777 $DIR/$tdir/$tdir ||
2787                 error "$DIR/$tdir: chmod failed"
2788         chmod 777 $DIR/$tdir/${tdir}2 ||
2789                 error "$DIR/${tdir}2: chmod failed"
2790
2791         # chown should work
2792         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2793                 error "$DIR/$tdir: chown failed"
2794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2795                 error "$DIR/${tdir}2: chown failed"
2796
2797         # rename should work
2798         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2799                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2800         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2801                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2802
2803         #remove foreign dir
2804         rmdir $DIR/$tdir/${tdir}.new ||
2805                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2806         rmdir $DIR/$tdir/${tdir}2.new ||
2807                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2808 }
2809 run_test 27K "basic ops on dir with foreign LMV"
2810
2811 # createtest also checks that device nodes are created and
2812 # then visible correctly (#2091)
2813 test_28() { # bug 2091
2814         test_mkdir $DIR/d28
2815         $CREATETEST $DIR/d28/ct || error "createtest failed"
2816 }
2817 run_test 28 "create/mknod/mkdir with bad file types ============"
2818
2819 test_29() {
2820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2821
2822         sync; sleep 1; sync # flush out any dirty pages from previous tests
2823         cancel_lru_locks
2824         test_mkdir $DIR/d29
2825         touch $DIR/d29/foo
2826         log 'first d29'
2827         ls -l $DIR/d29
2828
2829         declare -i LOCKCOUNTORIG=0
2830         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2831                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2832         done
2833         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2834
2835         declare -i LOCKUNUSEDCOUNTORIG=0
2836         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2837                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2838         done
2839
2840         log 'second d29'
2841         ls -l $DIR/d29
2842         log 'done'
2843
2844         declare -i LOCKCOUNTCURRENT=0
2845         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2846                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2847         done
2848
2849         declare -i LOCKUNUSEDCOUNTCURRENT=0
2850         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2851                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2852         done
2853
2854         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2855                 $LCTL set_param -n ldlm.dump_namespaces ""
2856                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2857                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2858                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2859                 return 2
2860         fi
2861         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2862                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2863                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2864                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2865                 return 3
2866         fi
2867 }
2868 run_test 29 "IT_GETATTR regression  ============================"
2869
2870 test_30a() { # was test_30
2871         cp $(which ls) $DIR || cp /bin/ls $DIR
2872         $DIR/ls / || error "Can't execute binary from lustre"
2873         rm $DIR/ls
2874 }
2875 run_test 30a "execute binary from Lustre (execve) =============="
2876
2877 test_30b() {
2878         cp `which ls` $DIR || cp /bin/ls $DIR
2879         chmod go+rx $DIR/ls
2880         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2881         rm $DIR/ls
2882 }
2883 run_test 30b "execute binary from Lustre as non-root ==========="
2884
2885 test_30c() { # b=22376
2886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2887
2888         cp `which ls` $DIR || cp /bin/ls $DIR
2889         chmod a-rw $DIR/ls
2890         cancel_lru_locks mdc
2891         cancel_lru_locks osc
2892         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2893         rm -f $DIR/ls
2894 }
2895 run_test 30c "execute binary from Lustre without read perms ===="
2896
2897 test_31a() {
2898         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2899         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2900 }
2901 run_test 31a "open-unlink file =================================="
2902
2903 test_31b() {
2904         touch $DIR/f31 || error "touch $DIR/f31 failed"
2905         ln $DIR/f31 $DIR/f31b || error "ln failed"
2906         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2907         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2908 }
2909 run_test 31b "unlink file with multiple links while open ======="
2910
2911 test_31c() {
2912         touch $DIR/f31 || error "touch $DIR/f31 failed"
2913         ln $DIR/f31 $DIR/f31c || error "ln failed"
2914         multiop_bg_pause $DIR/f31 O_uc ||
2915                 error "multiop_bg_pause for $DIR/f31 failed"
2916         MULTIPID=$!
2917         $MULTIOP $DIR/f31c Ouc
2918         kill -USR1 $MULTIPID
2919         wait $MULTIPID
2920 }
2921 run_test 31c "open-unlink file with multiple links ============="
2922
2923 test_31d() {
2924         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2925         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2926 }
2927 run_test 31d "remove of open directory ========================="
2928
2929 test_31e() { # bug 2904
2930         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2931 }
2932 run_test 31e "remove of open non-empty directory ==============="
2933
2934 test_31f() { # bug 4554
2935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2936
2937         set -vx
2938         test_mkdir $DIR/d31f
2939         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2940         cp /etc/hosts $DIR/d31f
2941         ls -l $DIR/d31f
2942         $LFS getstripe $DIR/d31f/hosts
2943         multiop_bg_pause $DIR/d31f D_c || return 1
2944         MULTIPID=$!
2945
2946         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2947         test_mkdir $DIR/d31f
2948         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2949         cp /etc/hosts $DIR/d31f
2950         ls -l $DIR/d31f
2951         $LFS getstripe $DIR/d31f/hosts
2952         multiop_bg_pause $DIR/d31f D_c || return 1
2953         MULTIPID2=$!
2954
2955         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2956         wait $MULTIPID || error "first opendir $MULTIPID failed"
2957
2958         sleep 6
2959
2960         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2961         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2962         set +vx
2963 }
2964 run_test 31f "remove of open directory with open-unlink file ==="
2965
2966 test_31g() {
2967         echo "-- cross directory link --"
2968         test_mkdir -c1 $DIR/${tdir}ga
2969         test_mkdir -c1 $DIR/${tdir}gb
2970         touch $DIR/${tdir}ga/f
2971         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2972         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2973         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2974         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2975         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2976 }
2977 run_test 31g "cross directory link==============="
2978
2979 test_31h() {
2980         echo "-- cross directory link --"
2981         test_mkdir -c1 $DIR/${tdir}
2982         test_mkdir -c1 $DIR/${tdir}/dir
2983         touch $DIR/${tdir}/f
2984         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
2985         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
2986         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
2987         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
2988         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
2989 }
2990 run_test 31h "cross directory link under child==============="
2991
2992 test_31i() {
2993         echo "-- cross directory link --"
2994         test_mkdir -c1 $DIR/$tdir
2995         test_mkdir -c1 $DIR/$tdir/dir
2996         touch $DIR/$tdir/dir/f
2997         ln $DIR/$tdir/dir/f $DIR/$tdir/g
2998         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
2999         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3000         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3001         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3002 }
3003 run_test 31i "cross directory link under parent==============="
3004
3005 test_31j() {
3006         test_mkdir -c1 -p $DIR/$tdir
3007         test_mkdir -c1 -p $DIR/$tdir/dir1
3008         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3009         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3010         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3011         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3012         return 0
3013 }
3014 run_test 31j "link for directory==============="
3015
3016 test_31k() {
3017         test_mkdir -c1 -p $DIR/$tdir
3018         touch $DIR/$tdir/s
3019         touch $DIR/$tdir/exist
3020         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3021         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3022         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3023         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3024         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3025         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3026         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3027         return 0
3028 }
3029 run_test 31k "link to file: the same, non-existing, dir==============="
3030
3031 test_31m() {
3032         mkdir $DIR/d31m
3033         touch $DIR/d31m/s
3034         mkdir $DIR/d31m2
3035         touch $DIR/d31m2/exist
3036         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3037         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3038         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3039         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3040         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3041         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3042         return 0
3043 }
3044 run_test 31m "link to file: the same, non-existing, dir==============="
3045
3046 test_31n() {
3047         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3048         nlink=$(stat --format=%h $DIR/$tfile)
3049         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3050         local fd=$(free_fd)
3051         local cmd="exec $fd<$DIR/$tfile"
3052         eval $cmd
3053         cmd="exec $fd<&-"
3054         trap "eval $cmd" EXIT
3055         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3056         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3057         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3058         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3059         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3060         eval $cmd
3061 }
3062 run_test 31n "check link count of unlinked file"
3063
3064 link_one() {
3065         local TEMPNAME=$(mktemp $1_XXXXXX)
3066         mlink $TEMPNAME $1 2> /dev/null &&
3067                 echo "$BASHPID: link $TEMPNAME to $1 succeeded"
3068         munlink $TEMPNAME
3069 }
3070
3071 test_31o() { # LU-2901
3072         test_mkdir $DIR/$tdir
3073         for LOOP in $(seq 100); do
3074                 rm -f $DIR/$tdir/$tfile*
3075                 for THREAD in $(seq 8); do
3076                         link_one $DIR/$tdir/$tfile.$LOOP &
3077                 done
3078                 wait
3079                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3080                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3081                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3082                         break || true
3083         done
3084 }
3085 run_test 31o "duplicate hard links with same filename"
3086
3087 test_31p() {
3088         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3089
3090         test_mkdir $DIR/$tdir
3091         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3092         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3093
3094         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3095                 error "open unlink test1 failed"
3096         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3097                 error "open unlink test2 failed"
3098
3099         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3100                 error "test1 still exists"
3101         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3102                 error "test2 still exists"
3103 }
3104 run_test 31p "remove of open striped directory"
3105
3106 cleanup_test32_mount() {
3107         local rc=0
3108         trap 0
3109         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3110         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3111         losetup -d $loopdev || true
3112         rm -rf $DIR/$tdir
3113         return $rc
3114 }
3115
3116 test_32a() {
3117         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3118
3119         echo "== more mountpoints and symlinks ================="
3120         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3121         trap cleanup_test32_mount EXIT
3122         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3123         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3124                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3125         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3126                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3127         cleanup_test32_mount
3128 }
3129 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3130
3131 test_32b() {
3132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3133
3134         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3135         trap cleanup_test32_mount EXIT
3136         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3137         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3138                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3139         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3140                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3141         cleanup_test32_mount
3142 }
3143 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3144
3145 test_32c() {
3146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3147
3148         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3149         trap cleanup_test32_mount EXIT
3150         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3151         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3152                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3153         test_mkdir -p $DIR/$tdir/d2/test_dir
3154         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3155                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3156         cleanup_test32_mount
3157 }
3158 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3159
3160 test_32d() {
3161         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3162
3163         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3164         trap cleanup_test32_mount EXIT
3165         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3166         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3167                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3168         test_mkdir -p $DIR/$tdir/d2/test_dir
3169         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3170                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3171         cleanup_test32_mount
3172 }
3173 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3174
3175 test_32e() {
3176         rm -fr $DIR/$tdir
3177         test_mkdir -p $DIR/$tdir/tmp
3178         local tmp_dir=$DIR/$tdir/tmp
3179         ln -s $DIR/$tdir $tmp_dir/symlink11
3180         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3181         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3182         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3183 }
3184 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3185
3186 test_32f() {
3187         rm -fr $DIR/$tdir
3188         test_mkdir -p $DIR/$tdir/tmp
3189         local tmp_dir=$DIR/$tdir/tmp
3190         ln -s $DIR/$tdir $tmp_dir/symlink11
3191         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3192         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3193         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3194 }
3195 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3196
3197 test_32g() {
3198         local tmp_dir=$DIR/$tdir/tmp
3199         test_mkdir -p $tmp_dir
3200         test_mkdir $DIR/${tdir}2
3201         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3202         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3203         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3204         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3205         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3206         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3207 }
3208 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3209
3210 test_32h() {
3211         rm -fr $DIR/$tdir $DIR/${tdir}2
3212         tmp_dir=$DIR/$tdir/tmp
3213         test_mkdir -p $tmp_dir
3214         test_mkdir $DIR/${tdir}2
3215         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3216         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3217         ls $tmp_dir/symlink12 || error "listing symlink12"
3218         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3219 }
3220 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3221
3222 test_32i() {
3223         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3224
3225         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3226         trap cleanup_test32_mount EXIT
3227         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3228         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3229                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3230         touch $DIR/$tdir/test_file
3231         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3232                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3233         cleanup_test32_mount
3234 }
3235 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3236
3237 test_32j() {
3238         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3239
3240         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3241         trap cleanup_test32_mount EXIT
3242         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3243         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3244                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3245         touch $DIR/$tdir/test_file
3246         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3247                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3248         cleanup_test32_mount
3249 }
3250 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3251
3252 test_32k() {
3253         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3254
3255         rm -fr $DIR/$tdir
3256         trap cleanup_test32_mount EXIT
3257         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3258         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3259                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3260         test_mkdir -p $DIR/$tdir/d2
3261         touch $DIR/$tdir/d2/test_file || error "touch failed"
3262         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3263                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3264         cleanup_test32_mount
3265 }
3266 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3267
3268 test_32l() {
3269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3270
3271         rm -fr $DIR/$tdir
3272         trap cleanup_test32_mount EXIT
3273         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3274         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3275                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3276         test_mkdir -p $DIR/$tdir/d2
3277         touch $DIR/$tdir/d2/test_file || error "touch failed"
3278         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3279                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3280         cleanup_test32_mount
3281 }
3282 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3283
3284 test_32m() {
3285         rm -fr $DIR/d32m
3286         test_mkdir -p $DIR/d32m/tmp
3287         TMP_DIR=$DIR/d32m/tmp
3288         ln -s $DIR $TMP_DIR/symlink11
3289         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3290         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3291                 error "symlink11 not a link"
3292         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3293                 error "symlink01 not a link"
3294 }
3295 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3296
3297 test_32n() {
3298         rm -fr $DIR/d32n
3299         test_mkdir -p $DIR/d32n/tmp
3300         TMP_DIR=$DIR/d32n/tmp
3301         ln -s $DIR $TMP_DIR/symlink11
3302         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3303         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3304         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3305 }
3306 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3307
3308 test_32o() {
3309         touch $DIR/$tfile
3310         test_mkdir -p $DIR/d32o/tmp
3311         TMP_DIR=$DIR/d32o/tmp
3312         ln -s $DIR/$tfile $TMP_DIR/symlink12
3313         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3314         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3315                 error "symlink12 not a link"
3316         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3317         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3318                 error "$DIR/d32o/tmp/symlink12 not file type"
3319         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3320                 error "$DIR/d32o/symlink02 not file type"
3321 }
3322 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3323
3324 test_32p() {
3325         log 32p_1
3326         rm -fr $DIR/d32p
3327         log 32p_2
3328         rm -f $DIR/$tfile
3329         log 32p_3
3330         touch $DIR/$tfile
3331         log 32p_4
3332         test_mkdir -p $DIR/d32p/tmp
3333         log 32p_5
3334         TMP_DIR=$DIR/d32p/tmp
3335         log 32p_6
3336         ln -s $DIR/$tfile $TMP_DIR/symlink12
3337         log 32p_7
3338         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3339         log 32p_8
3340         cat $DIR/d32p/tmp/symlink12 ||
3341                 error "Can't open $DIR/d32p/tmp/symlink12"
3342         log 32p_9
3343         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3344         log 32p_10
3345 }
3346 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3347
3348 test_32q() {
3349         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3350
3351         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3352         trap cleanup_test32_mount EXIT
3353         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3354         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3355         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3356                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3357         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3358         cleanup_test32_mount
3359 }
3360 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3361
3362 test_32r() {
3363         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3364
3365         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3366         trap cleanup_test32_mount EXIT
3367         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3368         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3369         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3370                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3371         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3372         cleanup_test32_mount
3373 }
3374 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3375
3376 test_33aa() {
3377         rm -f $DIR/$tfile
3378         touch $DIR/$tfile
3379         chmod 444 $DIR/$tfile
3380         chown $RUNAS_ID $DIR/$tfile
3381         log 33_1
3382         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3383         log 33_2
3384 }
3385 run_test 33aa "write file with mode 444 (should return error)"
3386
3387 test_33a() {
3388         rm -fr $DIR/$tdir
3389         test_mkdir $DIR/$tdir
3390         chown $RUNAS_ID $DIR/$tdir
3391         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3392                 error "$RUNAS create $tdir/$tfile failed"
3393         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3394                 error "open RDWR" || true
3395 }
3396 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3397
3398 test_33b() {
3399         rm -fr $DIR/$tdir
3400         test_mkdir $DIR/$tdir
3401         chown $RUNAS_ID $DIR/$tdir
3402         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3403 }
3404 run_test 33b "test open file with malformed flags (No panic)"
3405
3406 test_33c() {
3407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3408         remote_ost_nodsh && skip "remote OST with nodsh"
3409
3410         local ostnum
3411         local ostname
3412         local write_bytes
3413         local all_zeros
3414
3415         all_zeros=:
3416         rm -fr $DIR/$tdir
3417         test_mkdir $DIR/$tdir
3418         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3419
3420         sync
3421         for ostnum in $(seq $OSTCOUNT); do
3422                 # test-framework's OST numbering is one-based, while Lustre's
3423                 # is zero-based
3424                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3425                 # Parsing llobdstat's output sucks; we could grep the /proc
3426                 # path, but that's likely to not be as portable as using the
3427                 # llobdstat utility.  So we parse lctl output instead.
3428                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3429                         obdfilter/$ostname/stats |
3430                         awk '/^write_bytes/ {print $7}' )
3431                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3432                 if (( ${write_bytes:-0} > 0 ))
3433                 then
3434                         all_zeros=false
3435                         break;
3436                 fi
3437         done
3438
3439         $all_zeros || return 0
3440
3441         # Write four bytes
3442         echo foo > $DIR/$tdir/bar
3443         # Really write them
3444         sync
3445
3446         # Total up write_bytes after writing.  We'd better find non-zeros.
3447         for ostnum in $(seq $OSTCOUNT); do
3448                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3449                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3450                         obdfilter/$ostname/stats |
3451                         awk '/^write_bytes/ {print $7}' )
3452                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3453                 if (( ${write_bytes:-0} > 0 ))
3454                 then
3455                         all_zeros=false
3456                         break;
3457                 fi
3458         done
3459
3460         if $all_zeros
3461         then
3462                 for ostnum in $(seq $OSTCOUNT); do
3463                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3464                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3465                         do_facet ost$ostnum lctl get_param -n \
3466                                 obdfilter/$ostname/stats
3467                 done
3468                 error "OST not keeping write_bytes stats (b22312)"
3469         fi
3470 }
3471 run_test 33c "test llobdstat and write_bytes"
3472
3473 test_33d() {
3474         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3476
3477         local MDTIDX=1
3478         local remote_dir=$DIR/$tdir/remote_dir
3479
3480         test_mkdir $DIR/$tdir
3481         $LFS mkdir -i $MDTIDX $remote_dir ||
3482                 error "create remote directory failed"
3483
3484         touch $remote_dir/$tfile
3485         chmod 444 $remote_dir/$tfile
3486         chown $RUNAS_ID $remote_dir/$tfile
3487
3488         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3489
3490         chown $RUNAS_ID $remote_dir
3491         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3492                                         error "create" || true
3493         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3494                                     error "open RDWR" || true
3495         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3496 }
3497 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3498
3499 test_33e() {
3500         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3501
3502         mkdir $DIR/$tdir
3503
3504         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3505         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3506         mkdir $DIR/$tdir/local_dir
3507
3508         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3509         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3510         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3511
3512         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3513                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3514
3515         rmdir $DIR/$tdir/* || error "rmdir failed"
3516
3517         umask 777
3518         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3519         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3520         mkdir $DIR/$tdir/local_dir
3521
3522         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3523         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3524         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3525
3526         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3527                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3528
3529         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3530
3531         umask 000
3532         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3533         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3534         mkdir $DIR/$tdir/local_dir
3535
3536         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3537         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3538         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3539
3540         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3541                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3542 }
3543 run_test 33e "mkdir and striped directory should have same mode"
3544
3545 cleanup_33f() {
3546         trap 0
3547         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3548 }
3549
3550 test_33f() {
3551         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3552         remote_mds_nodsh && skip "remote MDS with nodsh"
3553
3554         mkdir $DIR/$tdir
3555         chmod go+rwx $DIR/$tdir
3556         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3557         trap cleanup_33f EXIT
3558
3559         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3560                 error "cannot create striped directory"
3561
3562         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3563                 error "cannot create files in striped directory"
3564
3565         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3566                 error "cannot remove files in striped directory"
3567
3568         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3569                 error "cannot remove striped directory"
3570
3571         cleanup_33f
3572 }
3573 run_test 33f "nonroot user can create, access, and remove a striped directory"
3574
3575 test_33g() {
3576         mkdir -p $DIR/$tdir/dir2
3577
3578         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3579         echo $err
3580         [[ $err =~ "exists" ]] || error "Not exists error"
3581 }
3582 run_test 33g "nonroot user create already existing root created file"
3583
3584 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3585 test_34a() {
3586         rm -f $DIR/f34
3587         $MCREATE $DIR/f34 || error "mcreate failed"
3588         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3589                 error "getstripe failed"
3590         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3591         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3592                 error "getstripe failed"
3593         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3594                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3595 }
3596 run_test 34a "truncate file that has not been opened ==========="
3597
3598 test_34b() {
3599         [ ! -f $DIR/f34 ] && test_34a
3600         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3601                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3602         $OPENFILE -f O_RDONLY $DIR/f34
3603         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3604                 error "getstripe failed"
3605         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3606                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3607 }
3608 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3609
3610 test_34c() {
3611         [ ! -f $DIR/f34 ] && test_34a
3612         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3613                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3614         $OPENFILE -f O_RDWR $DIR/f34
3615         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3616                 error "$LFS getstripe failed"
3617         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3618                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3619 }
3620 run_test 34c "O_RDWR opening file-with-size works =============="
3621
3622 test_34d() {
3623         [ ! -f $DIR/f34 ] && test_34a
3624         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3625                 error "dd failed"
3626         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3627                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3628         rm $DIR/f34
3629 }
3630 run_test 34d "write to sparse file ============================="
3631
3632 test_34e() {
3633         rm -f $DIR/f34e
3634         $MCREATE $DIR/f34e || error "mcreate failed"
3635         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3636         $CHECKSTAT -s 1000 $DIR/f34e ||
3637                 error "Size of $DIR/f34e not equal to 1000 bytes"
3638         $OPENFILE -f O_RDWR $DIR/f34e
3639         $CHECKSTAT -s 1000 $DIR/f34e ||
3640                 error "Size of $DIR/f34e not equal to 1000 bytes"
3641 }
3642 run_test 34e "create objects, some with size and some without =="
3643
3644 test_34f() { # bug 6242, 6243
3645         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3646
3647         SIZE34F=48000
3648         rm -f $DIR/f34f
3649         $MCREATE $DIR/f34f || error "mcreate failed"
3650         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3651         dd if=$DIR/f34f of=$TMP/f34f
3652         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3653         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3654         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3655         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3656         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3657 }
3658 run_test 34f "read from a file with no objects until EOF ======="
3659
3660 test_34g() {
3661         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3662
3663         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3664                 error "dd failed"
3665         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3666         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3667                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3668         cancel_lru_locks osc
3669         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3670                 error "wrong size after lock cancel"
3671
3672         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3673         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3674                 error "expanding truncate failed"
3675         cancel_lru_locks osc
3676         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3677                 error "wrong expanded size after lock cancel"
3678 }
3679 run_test 34g "truncate long file ==============================="
3680
3681 test_34h() {
3682         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3683
3684         local gid=10
3685         local sz=1000
3686
3687         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3688         sync # Flush the cache so that multiop below does not block on cache
3689              # flush when getting the group lock
3690         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3691         MULTIPID=$!
3692
3693         # Since just timed wait is not good enough, let's do a sync write
3694         # that way we are sure enough time for a roundtrip + processing
3695         # passed + 2 seconds of extra margin.
3696         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3697         rm $DIR/${tfile}-1
3698         sleep 2
3699
3700         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3701                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3702                 kill -9 $MULTIPID
3703         fi
3704         wait $MULTIPID
3705         local nsz=`stat -c %s $DIR/$tfile`
3706         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3707 }
3708 run_test 34h "ftruncate file under grouplock should not block"
3709
3710 test_35a() {
3711         cp /bin/sh $DIR/f35a
3712         chmod 444 $DIR/f35a
3713         chown $RUNAS_ID $DIR/f35a
3714         $RUNAS $DIR/f35a && error || true
3715         rm $DIR/f35a
3716 }
3717 run_test 35a "exec file with mode 444 (should return and not leak)"
3718
3719 test_36a() {
3720         rm -f $DIR/f36
3721         utime $DIR/f36 || error "utime failed for MDS"
3722 }
3723 run_test 36a "MDS utime check (mknod, utime)"
3724
3725 test_36b() {
3726         echo "" > $DIR/f36
3727         utime $DIR/f36 || error "utime failed for OST"
3728 }
3729 run_test 36b "OST utime check (open, utime)"
3730
3731 test_36c() {
3732         rm -f $DIR/d36/f36
3733         test_mkdir $DIR/d36
3734         chown $RUNAS_ID $DIR/d36
3735         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3736 }
3737 run_test 36c "non-root MDS utime check (mknod, utime)"
3738
3739 test_36d() {
3740         [ ! -d $DIR/d36 ] && test_36c
3741         echo "" > $DIR/d36/f36
3742         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3743 }
3744 run_test 36d "non-root OST utime check (open, utime)"
3745
3746 test_36e() {
3747         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3748
3749         test_mkdir $DIR/$tdir
3750         touch $DIR/$tdir/$tfile
3751         $RUNAS utime $DIR/$tdir/$tfile &&
3752                 error "utime worked, expected failure" || true
3753 }
3754 run_test 36e "utime on non-owned file (should return error)"
3755
3756 subr_36fh() {
3757         local fl="$1"
3758         local LANG_SAVE=$LANG
3759         local LC_LANG_SAVE=$LC_LANG
3760         export LANG=C LC_LANG=C # for date language
3761
3762         DATESTR="Dec 20  2000"
3763         test_mkdir $DIR/$tdir
3764         lctl set_param fail_loc=$fl
3765         date; date +%s
3766         cp /etc/hosts $DIR/$tdir/$tfile
3767         sync & # write RPC generated with "current" inode timestamp, but delayed
3768         sleep 1
3769         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3770         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3771         cancel_lru_locks $OSC
3772         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3773         date; date +%s
3774         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3775                 echo "BEFORE: $LS_BEFORE" && \
3776                 echo "AFTER : $LS_AFTER" && \
3777                 echo "WANT  : $DATESTR" && \
3778                 error "$DIR/$tdir/$tfile timestamps changed" || true
3779
3780         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3781 }
3782
3783 test_36f() {
3784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3785
3786         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3787         subr_36fh "0x80000214"
3788 }
3789 run_test 36f "utime on file racing with OST BRW write =========="
3790
3791 test_36g() {
3792         remote_ost_nodsh && skip "remote OST with nodsh"
3793         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3794         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3795                 skip "Need MDS version at least 2.12.51"
3796
3797         local fmd_max_age
3798         local fmd
3799         local facet="ost1"
3800         local tgt="obdfilter"
3801
3802         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3803
3804         test_mkdir $DIR/$tdir
3805         fmd_max_age=$(do_facet $facet \
3806                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3807                 head -n 1")
3808
3809         echo "FMD max age: ${fmd_max_age}s"
3810         touch $DIR/$tdir/$tfile
3811         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3812                 gawk '{cnt=cnt+$1}  END{print cnt}')
3813         echo "FMD before: $fmd"
3814         [[ $fmd == 0 ]] &&
3815                 error "FMD wasn't create by touch"
3816         sleep $((fmd_max_age + 12))
3817         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3818                 gawk '{cnt=cnt+$1}  END{print cnt}')
3819         echo "FMD after: $fmd"
3820         [[ $fmd == 0 ]] ||
3821                 error "FMD wasn't expired by ping"
3822 }
3823 run_test 36g "FMD cache expiry ====================="
3824
3825 test_36h() {
3826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3827
3828         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3829         subr_36fh "0x80000227"
3830 }
3831 run_test 36h "utime on file racing with OST BRW write =========="
3832
3833 test_36i() {
3834         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3835
3836         test_mkdir $DIR/$tdir
3837         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3838
3839         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3840         local new_mtime=$((mtime + 200))
3841
3842         #change Modify time of striped dir
3843         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3844                         error "change mtime failed"
3845
3846         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3847
3848         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3849 }
3850 run_test 36i "change mtime on striped directory"
3851
3852 # test_37 - duplicate with tests 32q 32r
3853
3854 test_38() {
3855         local file=$DIR/$tfile
3856         touch $file
3857         openfile -f O_DIRECTORY $file
3858         local RC=$?
3859         local ENOTDIR=20
3860         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3861         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3862 }
3863 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3864
3865 test_39a() { # was test_39
3866         touch $DIR/$tfile
3867         touch $DIR/${tfile}2
3868 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3869 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3870 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3871         sleep 2
3872         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3873         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3874                 echo "mtime"
3875                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3876                 echo "atime"
3877                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3878                 echo "ctime"
3879                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3880                 error "O_TRUNC didn't change timestamps"
3881         fi
3882 }
3883 run_test 39a "mtime changed on create"
3884
3885 test_39b() {
3886         test_mkdir -c1 $DIR/$tdir
3887         cp -p /etc/passwd $DIR/$tdir/fopen
3888         cp -p /etc/passwd $DIR/$tdir/flink
3889         cp -p /etc/passwd $DIR/$tdir/funlink
3890         cp -p /etc/passwd $DIR/$tdir/frename
3891         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3892
3893         sleep 1
3894         echo "aaaaaa" >> $DIR/$tdir/fopen
3895         echo "aaaaaa" >> $DIR/$tdir/flink
3896         echo "aaaaaa" >> $DIR/$tdir/funlink
3897         echo "aaaaaa" >> $DIR/$tdir/frename
3898
3899         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3900         local link_new=`stat -c %Y $DIR/$tdir/flink`
3901         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3902         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3903
3904         cat $DIR/$tdir/fopen > /dev/null
3905         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3906         rm -f $DIR/$tdir/funlink2
3907         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3908
3909         for (( i=0; i < 2; i++ )) ; do
3910                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3911                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3912                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3913                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3914
3915                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3916                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3917                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3918                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3919
3920                 cancel_lru_locks $OSC
3921                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3922         done
3923 }
3924 run_test 39b "mtime change on open, link, unlink, rename  ======"
3925
3926 # this should be set to past
3927 TEST_39_MTIME=`date -d "1 year ago" +%s`
3928
3929 # bug 11063
3930 test_39c() {
3931         touch $DIR1/$tfile
3932         sleep 2
3933         local mtime0=`stat -c %Y $DIR1/$tfile`
3934
3935         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3936         local mtime1=`stat -c %Y $DIR1/$tfile`
3937         [ "$mtime1" = $TEST_39_MTIME ] || \
3938                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3939
3940         local d1=`date +%s`
3941         echo hello >> $DIR1/$tfile
3942         local d2=`date +%s`
3943         local mtime2=`stat -c %Y $DIR1/$tfile`
3944         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3945                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3946
3947         mv $DIR1/$tfile $DIR1/$tfile-1
3948
3949         for (( i=0; i < 2; i++ )) ; do
3950                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3951                 [ "$mtime2" = "$mtime3" ] || \
3952                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3953
3954                 cancel_lru_locks $OSC
3955                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3956         done
3957 }
3958 run_test 39c "mtime change on rename ==========================="
3959
3960 # bug 21114
3961 test_39d() {
3962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3963
3964         touch $DIR1/$tfile
3965         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3966
3967         for (( i=0; i < 2; i++ )) ; do
3968                 local mtime=`stat -c %Y $DIR1/$tfile`
3969                 [ $mtime = $TEST_39_MTIME ] || \
3970                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3971
3972                 cancel_lru_locks $OSC
3973                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3974         done
3975 }
3976 run_test 39d "create, utime, stat =============================="
3977
3978 # bug 21114
3979 test_39e() {
3980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3981
3982         touch $DIR1/$tfile
3983         local mtime1=`stat -c %Y $DIR1/$tfile`
3984
3985         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3986
3987         for (( i=0; i < 2; i++ )) ; do
3988                 local mtime2=`stat -c %Y $DIR1/$tfile`
3989                 [ $mtime2 = $TEST_39_MTIME ] || \
3990                         error "mtime($mtime2) 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 39e "create, stat, utime, stat ========================"
3997
3998 # bug 21114
3999 test_39f() {
4000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4001
4002         touch $DIR1/$tfile
4003         mtime1=`stat -c %Y $DIR1/$tfile`
4004
4005         sleep 2
4006         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4007
4008         for (( i=0; i < 2; i++ )) ; do
4009                 local mtime2=`stat -c %Y $DIR1/$tfile`
4010                 [ $mtime2 = $TEST_39_MTIME ] || \
4011                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4012
4013                 cancel_lru_locks $OSC
4014                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4015         done
4016 }
4017 run_test 39f "create, stat, sleep, utime, stat ================="
4018
4019 # bug 11063
4020 test_39g() {
4021         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4022
4023         echo hello >> $DIR1/$tfile
4024         local mtime1=`stat -c %Y $DIR1/$tfile`
4025
4026         sleep 2
4027         chmod o+r $DIR1/$tfile
4028
4029         for (( i=0; i < 2; i++ )) ; do
4030                 local mtime2=`stat -c %Y $DIR1/$tfile`
4031                 [ "$mtime1" = "$mtime2" ] || \
4032                         error "lost mtime: $mtime2, should be $mtime1"
4033
4034                 cancel_lru_locks $OSC
4035                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4036         done
4037 }
4038 run_test 39g "write, chmod, stat ==============================="
4039
4040 # bug 11063
4041 test_39h() {
4042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4043
4044         touch $DIR1/$tfile
4045         sleep 1
4046
4047         local d1=`date`
4048         echo hello >> $DIR1/$tfile
4049         local mtime1=`stat -c %Y $DIR1/$tfile`
4050
4051         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4052         local d2=`date`
4053         if [ "$d1" != "$d2" ]; then
4054                 echo "write and touch not within one second"
4055         else
4056                 for (( i=0; i < 2; i++ )) ; do
4057                         local mtime2=`stat -c %Y $DIR1/$tfile`
4058                         [ "$mtime2" = $TEST_39_MTIME ] || \
4059                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4060
4061                         cancel_lru_locks $OSC
4062                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4063                 done
4064         fi
4065 }
4066 run_test 39h "write, utime within one second, stat ============="
4067
4068 test_39i() {
4069         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4070
4071         touch $DIR1/$tfile
4072         sleep 1
4073
4074         echo hello >> $DIR1/$tfile
4075         local mtime1=`stat -c %Y $DIR1/$tfile`
4076
4077         mv $DIR1/$tfile $DIR1/$tfile-1
4078
4079         for (( i=0; i < 2; i++ )) ; do
4080                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4081
4082                 [ "$mtime1" = "$mtime2" ] || \
4083                         error "lost mtime: $mtime2, should be $mtime1"
4084
4085                 cancel_lru_locks $OSC
4086                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4087         done
4088 }
4089 run_test 39i "write, rename, stat =============================="
4090
4091 test_39j() {
4092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4093
4094         start_full_debug_logging
4095         touch $DIR1/$tfile
4096         sleep 1
4097
4098         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4099         lctl set_param fail_loc=0x80000412
4100         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4101                 error "multiop failed"
4102         local multipid=$!
4103         local mtime1=`stat -c %Y $DIR1/$tfile`
4104
4105         mv $DIR1/$tfile $DIR1/$tfile-1
4106
4107         kill -USR1 $multipid
4108         wait $multipid || error "multiop close failed"
4109
4110         for (( i=0; i < 2; i++ )) ; do
4111                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4112                 [ "$mtime1" = "$mtime2" ] ||
4113                         error "mtime is lost on close: $mtime2, " \
4114                               "should be $mtime1"
4115
4116                 cancel_lru_locks $OSC
4117                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4118         done
4119         lctl set_param fail_loc=0
4120         stop_full_debug_logging
4121 }
4122 run_test 39j "write, rename, close, stat ======================="
4123
4124 test_39k() {
4125         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4126
4127         touch $DIR1/$tfile
4128         sleep 1
4129
4130         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4131         local multipid=$!
4132         local mtime1=`stat -c %Y $DIR1/$tfile`
4133
4134         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4135
4136         kill -USR1 $multipid
4137         wait $multipid || error "multiop close failed"
4138
4139         for (( i=0; i < 2; i++ )) ; do
4140                 local mtime2=`stat -c %Y $DIR1/$tfile`
4141
4142                 [ "$mtime2" = $TEST_39_MTIME ] || \
4143                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4144
4145                 cancel_lru_locks osc
4146                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4147         done
4148 }
4149 run_test 39k "write, utime, close, stat ========================"
4150
4151 # this should be set to future
4152 TEST_39_ATIME=`date -d "1 year" +%s`
4153
4154 test_39l() {
4155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4156         remote_mds_nodsh && skip "remote MDS with nodsh"
4157
4158         local atime_diff=$(do_facet $SINGLEMDS \
4159                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4160         rm -rf $DIR/$tdir
4161         mkdir -p $DIR/$tdir
4162
4163         # test setting directory atime to future
4164         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4165         local atime=$(stat -c %X $DIR/$tdir)
4166         [ "$atime" = $TEST_39_ATIME ] ||
4167                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4168
4169         # test setting directory atime from future to now
4170         local now=$(date +%s)
4171         touch -a -d @$now $DIR/$tdir
4172
4173         atime=$(stat -c %X $DIR/$tdir)
4174         [ "$atime" -eq "$now"  ] ||
4175                 error "atime is not updated from future: $atime, $now"
4176
4177         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4178         sleep 3
4179
4180         # test setting directory atime when now > dir atime + atime_diff
4181         local d1=$(date +%s)
4182         ls $DIR/$tdir
4183         local d2=$(date +%s)
4184         cancel_lru_locks mdc
4185         atime=$(stat -c %X $DIR/$tdir)
4186         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4187                 error "atime is not updated  : $atime, should be $d2"
4188
4189         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4190         sleep 3
4191
4192         # test not setting directory atime when now < dir atime + atime_diff
4193         ls $DIR/$tdir
4194         cancel_lru_locks mdc
4195         atime=$(stat -c %X $DIR/$tdir)
4196         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4197                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4198
4199         do_facet $SINGLEMDS \
4200                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4201 }
4202 run_test 39l "directory atime update ==========================="
4203
4204 test_39m() {
4205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4206
4207         touch $DIR1/$tfile
4208         sleep 2
4209         local far_past_mtime=$(date -d "May 29 1953" +%s)
4210         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4211
4212         touch -m -d @$far_past_mtime $DIR1/$tfile
4213         touch -a -d @$far_past_atime $DIR1/$tfile
4214
4215         for (( i=0; i < 2; i++ )) ; do
4216                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4217                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4218                         error "atime or mtime set incorrectly"
4219
4220                 cancel_lru_locks $OSC
4221                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4222         done
4223 }
4224 run_test 39m "test atime and mtime before 1970"
4225
4226 test_39n() { # LU-3832
4227         remote_mds_nodsh && skip "remote MDS with nodsh"
4228
4229         local atime_diff=$(do_facet $SINGLEMDS \
4230                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4231         local atime0
4232         local atime1
4233         local atime2
4234
4235         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4236
4237         rm -rf $DIR/$tfile
4238         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4239         atime0=$(stat -c %X $DIR/$tfile)
4240
4241         sleep 5
4242         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4243         atime1=$(stat -c %X $DIR/$tfile)
4244
4245         sleep 5
4246         cancel_lru_locks mdc
4247         cancel_lru_locks osc
4248         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4249         atime2=$(stat -c %X $DIR/$tfile)
4250
4251         do_facet $SINGLEMDS \
4252                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4253
4254         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4255         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4256 }
4257 run_test 39n "check that O_NOATIME is honored"
4258
4259 test_39o() {
4260         TESTDIR=$DIR/$tdir/$tfile
4261         [ -e $TESTDIR ] && rm -rf $TESTDIR
4262         mkdir -p $TESTDIR
4263         cd $TESTDIR
4264         links1=2
4265         ls
4266         mkdir a b
4267         ls
4268         links2=$(stat -c %h .)
4269         [ $(($links1 + 2)) != $links2 ] &&
4270                 error "wrong links count $(($links1 + 2)) != $links2"
4271         rmdir b
4272         links3=$(stat -c %h .)
4273         [ $(($links1 + 1)) != $links3 ] &&
4274                 error "wrong links count $links1 != $links3"
4275         return 0
4276 }
4277 run_test 39o "directory cached attributes updated after create"
4278
4279 test_39p() {
4280         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4281
4282         local MDTIDX=1
4283         TESTDIR=$DIR/$tdir/$tdir
4284         [ -e $TESTDIR ] && rm -rf $TESTDIR
4285         test_mkdir -p $TESTDIR
4286         cd $TESTDIR
4287         links1=2
4288         ls
4289         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4290         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4291         ls
4292         links2=$(stat -c %h .)
4293         [ $(($links1 + 2)) != $links2 ] &&
4294                 error "wrong links count $(($links1 + 2)) != $links2"
4295         rmdir remote_dir2
4296         links3=$(stat -c %h .)
4297         [ $(($links1 + 1)) != $links3 ] &&
4298                 error "wrong links count $links1 != $links3"
4299         return 0
4300 }
4301 run_test 39p "remote directory cached attributes updated after create ========"
4302
4303
4304 test_39q() { # LU-8041
4305         local testdir=$DIR/$tdir
4306         mkdir -p $testdir
4307         multiop_bg_pause $testdir D_c || error "multiop failed"
4308         local multipid=$!
4309         cancel_lru_locks mdc
4310         kill -USR1 $multipid
4311         local atime=$(stat -c %X $testdir)
4312         [ "$atime" -ne 0 ] || error "atime is zero"
4313 }
4314 run_test 39q "close won't zero out atime"
4315
4316 test_40() {
4317         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4318         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4319                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4320         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4321                 error "$tfile is not 4096 bytes in size"
4322 }
4323 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4324
4325 test_41() {
4326         # bug 1553
4327         small_write $DIR/f41 18
4328 }
4329 run_test 41 "test small file write + fstat ====================="
4330
4331 count_ost_writes() {
4332         lctl get_param -n ${OSC}.*.stats |
4333                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4334                         END { printf("%0.0f", writes) }'
4335 }
4336
4337 # decent default
4338 WRITEBACK_SAVE=500
4339 DIRTY_RATIO_SAVE=40
4340 MAX_DIRTY_RATIO=50
4341 BG_DIRTY_RATIO_SAVE=10
4342 MAX_BG_DIRTY_RATIO=25
4343
4344 start_writeback() {
4345         trap 0
4346         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4347         # dirty_ratio, dirty_background_ratio
4348         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4349                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4350                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4351                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4352         else
4353                 # if file not here, we are a 2.4 kernel
4354                 kill -CONT `pidof kupdated`
4355         fi
4356 }
4357
4358 stop_writeback() {
4359         # setup the trap first, so someone cannot exit the test at the
4360         # exact wrong time and mess up a machine
4361         trap start_writeback EXIT
4362         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4363         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4364                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4365                 sysctl -w vm.dirty_writeback_centisecs=0
4366                 sysctl -w vm.dirty_writeback_centisecs=0
4367                 # save and increase /proc/sys/vm/dirty_ratio
4368                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4369                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4370                 # save and increase /proc/sys/vm/dirty_background_ratio
4371                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4372                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4373         else
4374                 # if file not here, we are a 2.4 kernel
4375                 kill -STOP `pidof kupdated`
4376         fi
4377 }
4378
4379 # ensure that all stripes have some grant before we test client-side cache
4380 setup_test42() {
4381         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4382                 dd if=/dev/zero of=$i bs=4k count=1
4383                 rm $i
4384         done
4385 }
4386
4387 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4388 # file truncation, and file removal.
4389 test_42a() {
4390         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4391
4392         setup_test42
4393         cancel_lru_locks $OSC
4394         stop_writeback
4395         sync; sleep 1; sync # just to be safe
4396         BEFOREWRITES=`count_ost_writes`
4397         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4398         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4399         AFTERWRITES=`count_ost_writes`
4400         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4401                 error "$BEFOREWRITES < $AFTERWRITES"
4402         start_writeback
4403 }
4404 run_test 42a "ensure that we don't flush on close"
4405
4406 test_42b() {
4407         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4408
4409         setup_test42
4410         cancel_lru_locks $OSC
4411         stop_writeback
4412         sync
4413         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4414         BEFOREWRITES=$(count_ost_writes)
4415         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4416         AFTERWRITES=$(count_ost_writes)
4417         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4418                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4419         fi
4420         BEFOREWRITES=$(count_ost_writes)
4421         sync || error "sync: $?"
4422         AFTERWRITES=$(count_ost_writes)
4423         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4424                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4425         fi
4426         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4427         start_writeback
4428         return 0
4429 }
4430 run_test 42b "test destroy of file with cached dirty data ======"
4431
4432 # if these tests just want to test the effect of truncation,
4433 # they have to be very careful.  consider:
4434 # - the first open gets a {0,EOF}PR lock
4435 # - the first write conflicts and gets a {0, count-1}PW
4436 # - the rest of the writes are under {count,EOF}PW
4437 # - the open for truncate tries to match a {0,EOF}PR
4438 #   for the filesize and cancels the PWs.
4439 # any number of fixes (don't get {0,EOF} on open, match
4440 # composite locks, do smarter file size management) fix
4441 # this, but for now we want these tests to verify that
4442 # the cancellation with truncate intent works, so we
4443 # start the file with a full-file pw lock to match against
4444 # until the truncate.
4445 trunc_test() {
4446         test=$1
4447         file=$DIR/$test
4448         offset=$2
4449         cancel_lru_locks $OSC
4450         stop_writeback
4451         # prime the file with 0,EOF PW to match
4452         touch $file
4453         $TRUNCATE $file 0
4454         sync; sync
4455         # now the real test..
4456         dd if=/dev/zero of=$file bs=1024 count=100
4457         BEFOREWRITES=`count_ost_writes`
4458         $TRUNCATE $file $offset
4459         cancel_lru_locks $OSC
4460         AFTERWRITES=`count_ost_writes`
4461         start_writeback
4462 }
4463
4464 test_42c() {
4465         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4466
4467         trunc_test 42c 1024
4468         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4469                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4470         rm $file
4471 }
4472 run_test 42c "test partial truncate of file with cached dirty data"
4473
4474 test_42d() {
4475         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4476
4477         trunc_test 42d 0
4478         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4479                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4480         rm $file
4481 }
4482 run_test 42d "test complete truncate of file with cached dirty data"
4483
4484 test_42e() { # bug22074
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         local TDIR=$DIR/${tdir}e
4488         local pages=16 # hardcoded 16 pages, don't change it.
4489         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4490         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4491         local max_dirty_mb
4492         local warmup_files
4493
4494         test_mkdir $DIR/${tdir}e
4495         $LFS setstripe -c 1 $TDIR
4496         createmany -o $TDIR/f $files
4497
4498         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4499
4500         # we assume that with $OSTCOUNT files, at least one of them will
4501         # be allocated on OST0.
4502         warmup_files=$((OSTCOUNT * max_dirty_mb))
4503         createmany -o $TDIR/w $warmup_files
4504
4505         # write a large amount of data into one file and sync, to get good
4506         # avail_grant number from OST.
4507         for ((i=0; i<$warmup_files; i++)); do
4508                 idx=$($LFS getstripe -i $TDIR/w$i)
4509                 [ $idx -ne 0 ] && continue
4510                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4511                 break
4512         done
4513         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4514         sync
4515         $LCTL get_param $proc_osc0/cur_dirty_bytes
4516         $LCTL get_param $proc_osc0/cur_grant_bytes
4517
4518         # create as much dirty pages as we can while not to trigger the actual
4519         # RPCs directly. but depends on the env, VFS may trigger flush during this
4520         # period, hopefully we are good.
4521         for ((i=0; i<$warmup_files; i++)); do
4522                 idx=$($LFS getstripe -i $TDIR/w$i)
4523                 [ $idx -ne 0 ] && continue
4524                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4525         done
4526         $LCTL get_param $proc_osc0/cur_dirty_bytes
4527         $LCTL get_param $proc_osc0/cur_grant_bytes
4528
4529         # perform the real test
4530         $LCTL set_param $proc_osc0/rpc_stats 0
4531         for ((;i<$files; i++)); do
4532                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4533                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4534         done
4535         sync
4536         $LCTL get_param $proc_osc0/rpc_stats
4537
4538         local percent=0
4539         local have_ppr=false
4540         $LCTL get_param $proc_osc0/rpc_stats |
4541                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4542                         # skip lines until we are at the RPC histogram data
4543                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4544                         $have_ppr || continue
4545
4546                         # we only want the percent stat for < 16 pages
4547                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4548
4549                         percent=$((percent + WPCT))
4550                         if [[ $percent -gt 15 ]]; then
4551                                 error "less than 16-pages write RPCs" \
4552                                       "$percent% > 15%"
4553                                 break
4554                         fi
4555                 done
4556         rm -rf $TDIR
4557 }
4558 run_test 42e "verify sub-RPC writes are not done synchronously"
4559
4560 test_43A() { # was test_43
4561         test_mkdir $DIR/$tdir
4562         cp -p /bin/ls $DIR/$tdir/$tfile
4563         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4564         pid=$!
4565         # give multiop a chance to open
4566         sleep 1
4567
4568         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4569         kill -USR1 $pid
4570 }
4571 run_test 43A "execution of file opened for write should return -ETXTBSY"
4572
4573 test_43a() {
4574         test_mkdir $DIR/$tdir
4575         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4576         $DIR/$tdir/sleep 60 &
4577         SLEEP_PID=$!
4578         # Make sure exec of $tdir/sleep wins race with truncate
4579         sleep 1
4580         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4581         kill $SLEEP_PID
4582 }
4583 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4584
4585 test_43b() {
4586         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4587
4588         test_mkdir $DIR/$tdir
4589         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4590         $DIR/$tdir/sleep 60 &
4591         SLEEP_PID=$!
4592         # Make sure exec of $tdir/sleep wins race with truncate
4593         sleep 1
4594         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4595         kill $SLEEP_PID
4596 }
4597 run_test 43b "truncate of file being executed should return -ETXTBSY"
4598
4599 test_43c() {
4600         local testdir="$DIR/$tdir"
4601         test_mkdir $testdir
4602         cp $SHELL $testdir/
4603         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4604                 ( cd $testdir && md5sum -c )
4605 }
4606 run_test 43c "md5sum of copy into lustre"
4607
4608 test_44A() { # was test_44
4609         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4610
4611         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4612         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4613 }
4614 run_test 44A "zero length read from a sparse stripe"
4615
4616 test_44a() {
4617         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4618                 awk '{ print $2 }')
4619         [ -z "$nstripe" ] && skip "can't get stripe info"
4620         [[ $nstripe -gt $OSTCOUNT ]] &&
4621                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4622
4623         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4624                 awk '{ print $2 }')
4625         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4626                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4627                         awk '{ print $2 }')
4628         fi
4629
4630         OFFSETS="0 $((stride/2)) $((stride-1))"
4631         for offset in $OFFSETS; do
4632                 for i in $(seq 0 $((nstripe-1))); do
4633                         local GLOBALOFFSETS=""
4634                         # size in Bytes
4635                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4636                         local myfn=$DIR/d44a-$size
4637                         echo "--------writing $myfn at $size"
4638                         ll_sparseness_write $myfn $size ||
4639                                 error "ll_sparseness_write"
4640                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4641                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4642                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4643
4644                         for j in $(seq 0 $((nstripe-1))); do
4645                                 # size in Bytes
4646                                 size=$((((j + $nstripe )*$stride + $offset)))
4647                                 ll_sparseness_write $myfn $size ||
4648                                         error "ll_sparseness_write"
4649                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4650                         done
4651                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4652                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4653                         rm -f $myfn
4654                 done
4655         done
4656 }
4657 run_test 44a "test sparse pwrite ==============================="
4658
4659 dirty_osc_total() {
4660         tot=0
4661         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4662                 tot=$(($tot + $d))
4663         done
4664         echo $tot
4665 }
4666 do_dirty_record() {
4667         before=`dirty_osc_total`
4668         echo executing "\"$*\""
4669         eval $*
4670         after=`dirty_osc_total`
4671         echo before $before, after $after
4672 }
4673 test_45() {
4674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4675
4676         f="$DIR/f45"
4677         # Obtain grants from OST if it supports it
4678         echo blah > ${f}_grant
4679         stop_writeback
4680         sync
4681         do_dirty_record "echo blah > $f"
4682         [[ $before -eq $after ]] && error "write wasn't cached"
4683         do_dirty_record "> $f"
4684         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4685         do_dirty_record "echo blah > $f"
4686         [[ $before -eq $after ]] && error "write wasn't cached"
4687         do_dirty_record "sync"
4688         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4689         do_dirty_record "echo blah > $f"
4690         [[ $before -eq $after ]] && error "write wasn't cached"
4691         do_dirty_record "cancel_lru_locks osc"
4692         [[ $before -gt $after ]] ||
4693                 error "lock cancellation didn't lower dirty count"
4694         start_writeback
4695 }
4696 run_test 45 "osc io page accounting ============================"
4697
4698 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4699 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4700 # objects offset and an assert hit when an rpc was built with 1023's mapped
4701 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4702 test_46() {
4703         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4704
4705         f="$DIR/f46"
4706         stop_writeback
4707         sync
4708         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4709         sync
4710         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4711         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4712         sync
4713         start_writeback
4714 }
4715 run_test 46 "dirtying a previously written page ================"
4716
4717 # test_47 is removed "Device nodes check" is moved to test_28
4718
4719 test_48a() { # bug 2399
4720         [ "$mds1_FSTYPE" = "zfs" ] &&
4721         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4722                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4723
4724         test_mkdir $DIR/$tdir
4725         cd $DIR/$tdir
4726         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4727         test_mkdir $DIR/$tdir
4728         touch foo || error "'touch foo' failed after recreating cwd"
4729         test_mkdir bar
4730         touch .foo || error "'touch .foo' failed after recreating cwd"
4731         test_mkdir .bar
4732         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4733         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4734         cd . || error "'cd .' failed after recreating cwd"
4735         mkdir . && error "'mkdir .' worked after recreating cwd"
4736         rmdir . && error "'rmdir .' worked after recreating cwd"
4737         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4738         cd .. || error "'cd ..' failed after recreating cwd"
4739 }
4740 run_test 48a "Access renamed working dir (should return errors)="
4741
4742 test_48b() { # bug 2399
4743         rm -rf $DIR/$tdir
4744         test_mkdir $DIR/$tdir
4745         cd $DIR/$tdir
4746         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4747         touch foo && error "'touch foo' worked after removing cwd"
4748         mkdir foo && error "'mkdir foo' worked after removing cwd"
4749         touch .foo && error "'touch .foo' worked after removing cwd"
4750         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4751         ls . > /dev/null && error "'ls .' worked after removing cwd"
4752         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4753         mkdir . && error "'mkdir .' worked after removing cwd"
4754         rmdir . && error "'rmdir .' worked after removing cwd"
4755         ln -s . foo && error "'ln -s .' worked after removing cwd"
4756         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4757 }
4758 run_test 48b "Access removed working dir (should return errors)="
4759
4760 test_48c() { # bug 2350
4761         #lctl set_param debug=-1
4762         #set -vx
4763         rm -rf $DIR/$tdir
4764         test_mkdir -p $DIR/$tdir/dir
4765         cd $DIR/$tdir/dir
4766         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4767         $TRACE touch foo && error "touch foo worked after removing cwd"
4768         $TRACE 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         $TRACE ls . && error "'ls .' worked after removing cwd"
4772         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4773         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4774         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4775         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4776         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4777 }
4778 run_test 48c "Access removed working subdir (should return errors)"
4779
4780 test_48d() { # 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 rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4788         $TRACE touch foo && error "'touch foo' worked after removing parent"
4789         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4790         touch .foo && error "'touch .foo' worked after removing parent"
4791         mkdir .foo && error "mkdir .foo worked after removing parent"
4792         $TRACE ls . && error "'ls .' worked after removing parent"
4793         $TRACE ls .. && error "'ls ..' worked after removing parent"
4794         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4795         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4796         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4797         true
4798 }
4799 run_test 48d "Access removed parent subdir (should return errors)"
4800
4801 test_48e() { # bug 4134
4802         #lctl set_param debug=-1
4803         #set -vx
4804         rm -rf $DIR/$tdir
4805         test_mkdir -p $DIR/$tdir/dir
4806         cd $DIR/$tdir/dir
4807         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4808         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4809         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4810         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4811         # On a buggy kernel addition of "touch foo" after cd .. will
4812         # produce kernel oops in lookup_hash_it
4813         touch ../foo && error "'cd ..' worked after recreate parent"
4814         cd $DIR
4815         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4816 }
4817 run_test 48e "Access to recreated parent subdir (should return errors)"
4818
4819 test_49() { # LU-1030
4820         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4821         remote_ost_nodsh && skip "remote OST with nodsh"
4822
4823         # get ost1 size - lustre-OST0000
4824         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4825                 awk '{ print $4 }')
4826         # write 800M at maximum
4827         [[ $ost1_size -lt 2 ]] && ost1_size=2
4828         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4829
4830         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4831         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4832         local dd_pid=$!
4833
4834         # change max_pages_per_rpc while writing the file
4835         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4836         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4837         # loop until dd process exits
4838         while ps ax -opid | grep -wq $dd_pid; do
4839                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4840                 sleep $((RANDOM % 5 + 1))
4841         done
4842         # restore original max_pages_per_rpc
4843         $LCTL set_param $osc1_mppc=$orig_mppc
4844         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4845 }
4846 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4847
4848 test_50() {
4849         # bug 1485
4850         test_mkdir $DIR/$tdir
4851         cd $DIR/$tdir
4852         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4853 }
4854 run_test 50 "special situations: /proc symlinks  ==============="
4855
4856 test_51a() {    # was test_51
4857         # bug 1516 - create an empty entry right after ".." then split dir
4858         test_mkdir -c1 $DIR/$tdir
4859         touch $DIR/$tdir/foo
4860         $MCREATE $DIR/$tdir/bar
4861         rm $DIR/$tdir/foo
4862         createmany -m $DIR/$tdir/longfile 201
4863         FNUM=202
4864         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4865                 $MCREATE $DIR/$tdir/longfile$FNUM
4866                 FNUM=$(($FNUM + 1))
4867                 echo -n "+"
4868         done
4869         echo
4870         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4871 }
4872 run_test 51a "special situations: split htree with empty entry =="
4873
4874 cleanup_print_lfs_df () {
4875         trap 0
4876         $LFS df
4877         $LFS df -i
4878 }
4879
4880 test_51b() {
4881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4882
4883         local dir=$DIR/$tdir
4884         local nrdirs=$((65536 + 100))
4885
4886         # cleanup the directory
4887         rm -fr $dir
4888
4889         test_mkdir -c1 $dir
4890
4891         $LFS df
4892         $LFS df -i
4893         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4894         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4895         [[ $numfree -lt $nrdirs ]] &&
4896                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4897
4898         # need to check free space for the directories as well
4899         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4900         numfree=$(( blkfree / $(fs_inode_ksize) ))
4901         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4902
4903         trap cleanup_print_lfs_df EXIT
4904
4905         # create files
4906         createmany -d $dir/d $nrdirs || {
4907                 unlinkmany $dir/d $nrdirs
4908                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4909         }
4910
4911         # really created :
4912         nrdirs=$(ls -U $dir | wc -l)
4913
4914         # unlink all but 100 subdirectories, then check it still works
4915         local left=100
4916         local delete=$((nrdirs - left))
4917
4918         $LFS df
4919         $LFS df -i
4920
4921         # for ldiskfs the nlink count should be 1, but this is OSD specific
4922         # and so this is listed for informational purposes only
4923         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4924         unlinkmany -d $dir/d $delete ||
4925                 error "unlink of first $delete subdirs failed"
4926
4927         echo "nlink between: $(stat -c %h $dir)"
4928         local found=$(ls -U $dir | wc -l)
4929         [ $found -ne $left ] &&
4930                 error "can't find subdirs: found only $found, expected $left"
4931
4932         unlinkmany -d $dir/d $delete $left ||
4933                 error "unlink of second $left subdirs failed"
4934         # regardless of whether the backing filesystem tracks nlink accurately
4935         # or not, the nlink count shouldn't be more than "." and ".." here
4936         local after=$(stat -c %h $dir)
4937         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4938                 echo "nlink after: $after"
4939
4940         cleanup_print_lfs_df
4941 }
4942 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4943
4944 test_51d() {
4945         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4946         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4947
4948         test_mkdir $DIR/$tdir
4949         createmany -o $DIR/$tdir/t- 1000
4950         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4951         for N in $(seq 0 $((OSTCOUNT - 1))); do
4952                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4953                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4954                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4955                         '($1 == '$N') { objs += 1 } \
4956                         END { printf("%0.0f", objs) }')
4957                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4958         done
4959         unlinkmany $DIR/$tdir/t- 1000
4960
4961         NLAST=0
4962         for N in $(seq 1 $((OSTCOUNT - 1))); do
4963                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4964                         error "OST $N has less objects vs OST $NLAST" \
4965                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4966                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4967                         error "OST $N has less objects vs OST $NLAST" \
4968                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4969
4970                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4971                         error "OST $N has less #0 objects vs OST $NLAST" \
4972                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4973                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4974                         error "OST $N has less #0 objects vs OST $NLAST" \
4975                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4976                 NLAST=$N
4977         done
4978         rm -f $TMP/$tfile
4979 }
4980 run_test 51d "check object distribution"
4981
4982 test_51e() {
4983         if [ "$mds1_FSTYPE" != ldiskfs ]; then
4984                 skip_env "ldiskfs only test"
4985         fi
4986
4987         test_mkdir -c1 $DIR/$tdir
4988         test_mkdir -c1 $DIR/$tdir/d0
4989
4990         touch $DIR/$tdir/d0/foo
4991         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
4992                 error "file exceed 65000 nlink limit!"
4993         unlinkmany $DIR/$tdir/d0/f- 65001
4994         return 0
4995 }
4996 run_test 51e "check file nlink limit"
4997
4998 test_51f() {
4999         test_mkdir $DIR/$tdir
5000
5001         local max=100000
5002         local ulimit_old=$(ulimit -n)
5003         local spare=20 # number of spare fd's for scripts/libraries, etc.
5004         local mdt=$($LFS getstripe -m $DIR/$tdir)
5005         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5006
5007         echo "MDT$mdt numfree=$numfree, max=$max"
5008         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5009         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5010                 while ! ulimit -n $((numfree + spare)); do
5011                         numfree=$((numfree * 3 / 4))
5012                 done
5013                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5014         else
5015                 echo "left ulimit at $ulimit_old"
5016         fi
5017
5018         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5019                 unlinkmany $DIR/$tdir/f $numfree
5020                 error "create+open $numfree files in $DIR/$tdir failed"
5021         }
5022         ulimit -n $ulimit_old
5023
5024         # if createmany exits at 120s there will be fewer than $numfree files
5025         unlinkmany $DIR/$tdir/f $numfree || true
5026 }
5027 run_test 51f "check many open files limit"
5028
5029 test_52a() {
5030         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5031         test_mkdir $DIR/$tdir
5032         touch $DIR/$tdir/foo
5033         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5034         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5035         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5036         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5037         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5038                                         error "link worked"
5039         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5040         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5041         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5042                                                      error "lsattr"
5043         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5044         cp -r $DIR/$tdir $TMP/
5045         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5046 }
5047 run_test 52a "append-only flag test (should return errors)"
5048
5049 test_52b() {
5050         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5051         test_mkdir $DIR/$tdir
5052         touch $DIR/$tdir/foo
5053         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5054         cat test > $DIR/$tdir/foo && error "cat test worked"
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 "echo worked"
5060         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5061         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5062         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5063         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5064                                                         error "lsattr"
5065         chattr -i $DIR/$tdir/foo || error "chattr failed"
5066
5067         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5068 }
5069 run_test 52b "immutable flag test (should return errors) ======="
5070
5071 test_53() {
5072         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5073         remote_mds_nodsh && skip "remote MDS with nodsh"
5074         remote_ost_nodsh && skip "remote OST with nodsh"
5075
5076         local param
5077         local param_seq
5078         local ostname
5079         local mds_last
5080         local mds_last_seq
5081         local ost_last
5082         local ost_last_seq
5083         local ost_last_id
5084         local ostnum
5085         local node
5086         local found=false
5087         local support_last_seq=true
5088
5089         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5090                 support_last_seq=false
5091
5092         # only test MDT0000
5093         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5094         local value
5095         for value in $(do_facet $SINGLEMDS \
5096                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5097                 param=$(echo ${value[0]} | cut -d "=" -f1)
5098                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5099
5100                 if $support_last_seq; then
5101                         param_seq=$(echo $param |
5102                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5103                         mds_last_seq=$(do_facet $SINGLEMDS \
5104                                        $LCTL get_param -n $param_seq)
5105                 fi
5106                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5107
5108                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5109                 node=$(facet_active_host ost$((ostnum+1)))
5110                 param="obdfilter.$ostname.last_id"
5111                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5112                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5113                         ost_last_id=$ost_last
5114
5115                         if $support_last_seq; then
5116                                 ost_last_id=$(echo $ost_last |
5117                                               awk -F':' '{print $2}' |
5118                                               sed -e "s/^0x//g")
5119                                 ost_last_seq=$(echo $ost_last |
5120                                                awk -F':' '{print $1}')
5121                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5122                         fi
5123
5124                         if [[ $ost_last_id != $mds_last ]]; then
5125                                 error "$ost_last_id != $mds_last"
5126                         else
5127                                 found=true
5128                                 break
5129                         fi
5130                 done
5131         done
5132         $found || error "can not match last_seq/last_id for $mdtosc"
5133         return 0
5134 }
5135 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5136
5137 test_54a() {
5138         perl -MSocket -e ';' || skip "no Socket perl module installed"
5139
5140         $SOCKETSERVER $DIR/socket ||
5141                 error "$SOCKETSERVER $DIR/socket failed: $?"
5142         $SOCKETCLIENT $DIR/socket ||
5143                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5144         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5145 }
5146 run_test 54a "unix domain socket test =========================="
5147
5148 test_54b() {
5149         f="$DIR/f54b"
5150         mknod $f c 1 3
5151         chmod 0666 $f
5152         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5153 }
5154 run_test 54b "char device works in lustre ======================"
5155
5156 find_loop_dev() {
5157         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5158         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5159         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5160
5161         for i in $(seq 3 7); do
5162                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5163                 LOOPDEV=$LOOPBASE$i
5164                 LOOPNUM=$i
5165                 break
5166         done
5167 }
5168
5169 cleanup_54c() {
5170         local rc=0
5171         loopdev="$DIR/loop54c"
5172
5173         trap 0
5174         $UMOUNT $DIR/$tdir || rc=$?
5175         losetup -d $loopdev || true
5176         losetup -d $LOOPDEV || true
5177         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5178         return $rc
5179 }
5180
5181 test_54c() {
5182         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5183
5184         loopdev="$DIR/loop54c"
5185
5186         find_loop_dev
5187         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5188         trap cleanup_54c EXIT
5189         mknod $loopdev b 7 $LOOPNUM
5190         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5191         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5192         losetup $loopdev $DIR/$tfile ||
5193                 error "can't set up $loopdev for $DIR/$tfile"
5194         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5195         test_mkdir $DIR/$tdir
5196         mount -t ext2 $loopdev $DIR/$tdir ||
5197                 error "error mounting $loopdev on $DIR/$tdir"
5198         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5199                 error "dd write"
5200         df $DIR/$tdir
5201         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5202                 error "dd read"
5203         cleanup_54c
5204 }
5205 run_test 54c "block device works in lustre ====================="
5206
5207 test_54d() {
5208         f="$DIR/f54d"
5209         string="aaaaaa"
5210         mknod $f p
5211         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5212 }
5213 run_test 54d "fifo device works in lustre ======================"
5214
5215 test_54e() {
5216         f="$DIR/f54e"
5217         string="aaaaaa"
5218         cp -aL /dev/console $f
5219         echo $string > $f || error "echo $string to $f failed"
5220 }
5221 run_test 54e "console/tty device works in lustre ======================"
5222
5223 test_56a() {
5224         local numfiles=3
5225         local dir=$DIR/$tdir
5226
5227         rm -rf $dir
5228         test_mkdir -p $dir/dir
5229         for i in $(seq $numfiles); do
5230                 touch $dir/file$i
5231                 touch $dir/dir/file$i
5232         done
5233
5234         local numcomp=$($LFS getstripe --component-count $dir)
5235
5236         [[ $numcomp == 0 ]] && numcomp=1
5237
5238         # test lfs getstripe with --recursive
5239         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5240
5241         [[ $filenum -eq $((numfiles * 2)) ]] ||
5242                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5243         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5244         [[ $filenum -eq $numfiles ]] ||
5245                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5246         echo "$LFS getstripe showed obdidx or l_ost_idx"
5247
5248         # test lfs getstripe with file instead of dir
5249         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5250         [[ $filenum -eq 1 ]] ||
5251                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5252         echo "$LFS getstripe file1 passed"
5253
5254         #test lfs getstripe with --verbose
5255         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5256         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5257                 error "$LFS getstripe --verbose $dir: "\
5258                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5259         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5260                 error "$LFS getstripe $dir: showed lmm_magic"
5261
5262         #test lfs getstripe with -v prints lmm_fid
5263         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5264         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5265                 error "$LFS getstripe -v $dir: "\
5266                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5267         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5268                 error "$LFS getstripe $dir: showed lmm_fid by default"
5269         echo "$LFS getstripe --verbose passed"
5270
5271         #check for FID information
5272         local fid1=$($LFS getstripe --fid $dir/file1)
5273         local fid2=$($LFS getstripe --verbose $dir/file1 |
5274                      awk '/lmm_fid: / { print $2; exit; }')
5275         local fid3=$($LFS path2fid $dir/file1)
5276
5277         [ "$fid1" != "$fid2" ] &&
5278                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5279         [ "$fid1" != "$fid3" ] &&
5280                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5281         echo "$LFS getstripe --fid passed"
5282
5283         #test lfs getstripe with --obd
5284         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5285                 error "$LFS getstripe --obd wrong_uuid: should return error"
5286
5287         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5288
5289         local ostidx=1
5290         local obduuid=$(ostuuid_from_index $ostidx)
5291         local found=$($LFS getstripe -r --obd $obduuid $dir |
5292                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5293
5294         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5295         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5296                 ((filenum--))
5297         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5298                 ((filenum--))
5299
5300         [[ $found -eq $filenum ]] ||
5301                 error "$LFS getstripe --obd: found $found expect $filenum"
5302         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5303                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5304                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5305                 error "$LFS getstripe --obd: should not show file on other obd"
5306         echo "$LFS getstripe --obd passed"
5307 }
5308 run_test 56a "check $LFS getstripe"
5309
5310 test_56b() {
5311         local dir=$DIR/$tdir
5312         local numdirs=3
5313
5314         test_mkdir $dir
5315         for i in $(seq $numdirs); do
5316                 test_mkdir $dir/dir$i
5317         done
5318
5319         # test lfs getdirstripe default mode is non-recursion, which is
5320         # different from lfs getstripe
5321         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5322
5323         [[ $dircnt -eq 1 ]] ||
5324                 error "$LFS getdirstripe: found $dircnt, not 1"
5325         dircnt=$($LFS getdirstripe --recursive $dir |
5326                 grep -c lmv_stripe_count)
5327         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5328                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5329 }
5330 run_test 56b "check $LFS getdirstripe"
5331
5332 test_56c() {
5333         remote_ost_nodsh && skip "remote OST with nodsh"
5334
5335         local ost_idx=0
5336         local ost_name=$(ostname_from_index $ost_idx)
5337         local old_status=$(ost_dev_status $ost_idx)
5338
5339         [[ -z "$old_status" ]] ||
5340                 skip_env "OST $ost_name is in $old_status status"
5341
5342         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5343         sleep_maxage
5344
5345         local new_status=$(ost_dev_status $ost_idx)
5346
5347         [[ "$new_status" = "D" ]] ||
5348                 error "OST $ost_name is in status of '$new_status', not 'D'"
5349
5350         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5351         sleep_maxage
5352
5353         new_status=$(ost_dev_status $ost_idx)
5354         [[ -z "$new_status" ]] ||
5355                 error "OST $ost_name is in status of '$new_status', not ''"
5356 }
5357 run_test 56c "check 'lfs df' showing device status"
5358
5359 NUMFILES=3
5360 NUMDIRS=3
5361 setup_56() {
5362         local local_tdir="$1"
5363         local local_numfiles="$2"
5364         local local_numdirs="$3"
5365         local dir_params="$4"
5366         local dir_stripe_params="$5"
5367
5368         if [ ! -d "$local_tdir" ] ; then
5369                 test_mkdir -p $dir_stripe_params $local_tdir
5370                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5371                 for i in $(seq $local_numfiles) ; do
5372                         touch $local_tdir/file$i
5373                 done
5374                 for i in $(seq $local_numdirs) ; do
5375                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5376                         for j in $(seq $local_numfiles) ; do
5377                                 touch $local_tdir/dir$i/file$j
5378                         done
5379                 done
5380         fi
5381 }
5382
5383 setup_56_special() {
5384         local local_tdir=$1
5385         local local_numfiles=$2
5386         local local_numdirs=$3
5387
5388         setup_56 $local_tdir $local_numfiles $local_numdirs
5389
5390         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5391                 for i in $(seq $local_numfiles) ; do
5392                         mknod $local_tdir/loop${i}b b 7 $i
5393                         mknod $local_tdir/null${i}c c 1 3
5394                         ln -s $local_tdir/file1 $local_tdir/link${i}
5395                 done
5396                 for i in $(seq $local_numdirs) ; do
5397                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5398                         mknod $local_tdir/dir$i/null${i}c c 1 3
5399                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5400                 done
5401         fi
5402 }
5403
5404 test_56g() {
5405         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5406         local expected=$(($NUMDIRS + 2))
5407
5408         setup_56 $dir $NUMFILES $NUMDIRS
5409
5410         # test lfs find with -name
5411         for i in $(seq $NUMFILES) ; do
5412                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5413
5414                 [ $nums -eq $expected ] ||
5415                         error "lfs find -name '*$i' $dir wrong: "\
5416                               "found $nums, expected $expected"
5417         done
5418 }
5419 run_test 56g "check lfs find -name"
5420
5421 test_56h() {
5422         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5423         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5424
5425         setup_56 $dir $NUMFILES $NUMDIRS
5426
5427         # test lfs find with ! -name
5428         for i in $(seq $NUMFILES) ; do
5429                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5430
5431                 [ $nums -eq $expected ] ||
5432                         error "lfs find ! -name '*$i' $dir wrong: "\
5433                               "found $nums, expected $expected"
5434         done
5435 }
5436 run_test 56h "check lfs find ! -name"
5437
5438 test_56i() {
5439         local dir=$DIR/$tdir
5440
5441         test_mkdir $dir
5442
5443         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5444         local out=$($cmd)
5445
5446         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5447 }
5448 run_test 56i "check 'lfs find -ost UUID' skips directories"
5449
5450 test_56j() {
5451         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5452
5453         setup_56_special $dir $NUMFILES $NUMDIRS
5454
5455         local expected=$((NUMDIRS + 1))
5456         local cmd="$LFS find -type d $dir"
5457         local nums=$($cmd | wc -l)
5458
5459         [ $nums -eq $expected ] ||
5460                 error "'$cmd' wrong: found $nums, expected $expected"
5461 }
5462 run_test 56j "check lfs find -type d"
5463
5464 test_56k() {
5465         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5466
5467         setup_56_special $dir $NUMFILES $NUMDIRS
5468
5469         local expected=$(((NUMDIRS + 1) * NUMFILES))
5470         local cmd="$LFS find -type f $dir"
5471         local nums=$($cmd | wc -l)
5472
5473         [ $nums -eq $expected ] ||
5474                 error "'$cmd' wrong: found $nums, expected $expected"
5475 }
5476 run_test 56k "check lfs find -type f"
5477
5478 test_56l() {
5479         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5480
5481         setup_56_special $dir $NUMFILES $NUMDIRS
5482
5483         local expected=$((NUMDIRS + NUMFILES))
5484         local cmd="$LFS find -type b $dir"
5485         local nums=$($cmd | wc -l)
5486
5487         [ $nums -eq $expected ] ||
5488                 error "'$cmd' wrong: found $nums, expected $expected"
5489 }
5490 run_test 56l "check lfs find -type b"
5491
5492 test_56m() {
5493         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5494
5495         setup_56_special $dir $NUMFILES $NUMDIRS
5496
5497         local expected=$((NUMDIRS + NUMFILES))
5498         local cmd="$LFS find -type c $dir"
5499         local nums=$($cmd | wc -l)
5500         [ $nums -eq $expected ] ||
5501                 error "'$cmd' wrong: found $nums, expected $expected"
5502 }
5503 run_test 56m "check lfs find -type c"
5504
5505 test_56n() {
5506         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5507         setup_56_special $dir $NUMFILES $NUMDIRS
5508
5509         local expected=$((NUMDIRS + NUMFILES))
5510         local cmd="$LFS find -type l $dir"
5511         local nums=$($cmd | wc -l)
5512
5513         [ $nums -eq $expected ] ||
5514                 error "'$cmd' wrong: found $nums, expected $expected"
5515 }
5516 run_test 56n "check lfs find -type l"
5517
5518 test_56o() {
5519         local dir=$DIR/$tdir
5520
5521         setup_56 $dir $NUMFILES $NUMDIRS
5522         utime $dir/file1 > /dev/null || error "utime (1)"
5523         utime $dir/file2 > /dev/null || error "utime (2)"
5524         utime $dir/dir1 > /dev/null || error "utime (3)"
5525         utime $dir/dir2 > /dev/null || error "utime (4)"
5526         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5527         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5528
5529         local expected=4
5530         local nums=$($LFS find -mtime +0 $dir | wc -l)
5531
5532         [ $nums -eq $expected ] ||
5533                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5534
5535         expected=12
5536         cmd="$LFS find -mtime 0 $dir"
5537         nums=$($cmd | wc -l)
5538         [ $nums -eq $expected ] ||
5539                 error "'$cmd' wrong: found $nums, expected $expected"
5540 }
5541 run_test 56o "check lfs find -mtime for old files"
5542
5543 test_56ob() {
5544         local dir=$DIR/$tdir
5545         local expected=1
5546         local count=0
5547
5548         # just to make sure there is something that won't be found
5549         test_mkdir $dir
5550         touch $dir/$tfile.now
5551
5552         for age in year week day hour min; do
5553                 count=$((count + 1))
5554
5555                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5556                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5557                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5558
5559                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5560                 local nums=$($cmd | wc -l)
5561                 [ $nums -eq $expected ] ||
5562                         error "'$cmd' wrong: found $nums, expected $expected"
5563
5564                 cmd="$LFS find $dir -atime $count${age:0:1}"
5565                 nums=$($cmd | wc -l)
5566                 [ $nums -eq $expected ] ||
5567                         error "'$cmd' wrong: found $nums, expected $expected"
5568         done
5569
5570         sleep 2
5571         cmd="$LFS find $dir -ctime +1s -type f"
5572         nums=$($cmd | wc -l)
5573         (( $nums == $count * 2 + 1)) ||
5574                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5575 }
5576 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5577
5578 test_56p() {
5579         [ $RUNAS_ID -eq $UID ] &&
5580                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5581
5582         local dir=$DIR/$tdir
5583
5584         setup_56 $dir $NUMFILES $NUMDIRS
5585         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5586
5587         local expected=$NUMFILES
5588         local cmd="$LFS find -uid $RUNAS_ID $dir"
5589         local nums=$($cmd | wc -l)
5590
5591         [ $nums -eq $expected ] ||
5592                 error "'$cmd' wrong: found $nums, expected $expected"
5593
5594         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5595         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5596         nums=$($cmd | wc -l)
5597         [ $nums -eq $expected ] ||
5598                 error "'$cmd' wrong: found $nums, expected $expected"
5599 }
5600 run_test 56p "check lfs find -uid and ! -uid"
5601
5602 test_56q() {
5603         [ $RUNAS_ID -eq $UID ] &&
5604                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5605
5606         local dir=$DIR/$tdir
5607
5608         setup_56 $dir $NUMFILES $NUMDIRS
5609         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5610
5611         local expected=$NUMFILES
5612         local cmd="$LFS find -gid $RUNAS_GID $dir"
5613         local nums=$($cmd | wc -l)
5614
5615         [ $nums -eq $expected ] ||
5616                 error "'$cmd' wrong: found $nums, expected $expected"
5617
5618         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5619         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5620         nums=$($cmd | wc -l)
5621         [ $nums -eq $expected ] ||
5622                 error "'$cmd' wrong: found $nums, expected $expected"
5623 }
5624 run_test 56q "check lfs find -gid and ! -gid"
5625
5626 test_56r() {
5627         local dir=$DIR/$tdir
5628
5629         setup_56 $dir $NUMFILES $NUMDIRS
5630
5631         local expected=12
5632         local cmd="$LFS find -size 0 -type f $dir"
5633         local nums=$($cmd | wc -l)
5634
5635         [ $nums -eq $expected ] ||
5636                 error "'$cmd' wrong: found $nums, expected $expected"
5637         expected=0
5638         cmd="$LFS find ! -size 0 -type f $dir"
5639         nums=$($cmd | wc -l)
5640         [ $nums -eq $expected ] ||
5641                 error "'$cmd' wrong: found $nums, expected $expected"
5642         echo "test" > $dir/$tfile
5643         echo "test2" > $dir/$tfile.2 && sync
5644         expected=1
5645         cmd="$LFS find -size 5 -type f $dir"
5646         nums=$($cmd | wc -l)
5647         [ $nums -eq $expected ] ||
5648                 error "'$cmd' wrong: found $nums, expected $expected"
5649         expected=1
5650         cmd="$LFS find -size +5 -type f $dir"
5651         nums=$($cmd | wc -l)
5652         [ $nums -eq $expected ] ||
5653                 error "'$cmd' wrong: found $nums, expected $expected"
5654         expected=2
5655         cmd="$LFS find -size +0 -type f $dir"
5656         nums=$($cmd | wc -l)
5657         [ $nums -eq $expected ] ||
5658                 error "'$cmd' wrong: found $nums, expected $expected"
5659         expected=2
5660         cmd="$LFS find ! -size -5 -type f $dir"
5661         nums=$($cmd | wc -l)
5662         [ $nums -eq $expected ] ||
5663                 error "'$cmd' wrong: found $nums, expected $expected"
5664         expected=12
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 }
5670 run_test 56r "check lfs find -size works"
5671
5672 test_56s() { # LU-611 #LU-9369
5673         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5674
5675         local dir=$DIR/$tdir
5676         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5677
5678         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5679         for i in $(seq $NUMDIRS); do
5680                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5681         done
5682
5683         local expected=$NUMDIRS
5684         local cmd="$LFS find -c $OSTCOUNT $dir"
5685         local nums=$($cmd | wc -l)
5686
5687         [ $nums -eq $expected ] || {
5688                 $LFS getstripe -R $dir
5689                 error "'$cmd' wrong: found $nums, expected $expected"
5690         }
5691
5692         expected=$((NUMDIRS + onestripe))
5693         cmd="$LFS find -stripe-count +0 -type f $dir"
5694         nums=$($cmd | wc -l)
5695         [ $nums -eq $expected ] || {
5696                 $LFS getstripe -R $dir
5697                 error "'$cmd' wrong: found $nums, expected $expected"
5698         }
5699
5700         expected=$onestripe
5701         cmd="$LFS find -stripe-count 1 -type f $dir"
5702         nums=$($cmd | wc -l)
5703         [ $nums -eq $expected ] || {
5704                 $LFS getstripe -R $dir
5705                 error "'$cmd' wrong: found $nums, expected $expected"
5706         }
5707
5708         cmd="$LFS find -stripe-count -2 -type f $dir"
5709         nums=$($cmd | wc -l)
5710         [ $nums -eq $expected ] || {
5711                 $LFS getstripe -R $dir
5712                 error "'$cmd' wrong: found $nums, expected $expected"
5713         }
5714
5715         expected=0
5716         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5717         nums=$($cmd | wc -l)
5718         [ $nums -eq $expected ] || {
5719                 $LFS getstripe -R $dir
5720                 error "'$cmd' wrong: found $nums, expected $expected"
5721         }
5722 }
5723 run_test 56s "check lfs find -stripe-count works"
5724
5725 test_56t() { # LU-611 #LU-9369
5726         local dir=$DIR/$tdir
5727
5728         setup_56 $dir 0 $NUMDIRS
5729         for i in $(seq $NUMDIRS); do
5730                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5731         done
5732
5733         local expected=$NUMDIRS
5734         local cmd="$LFS find -S 8M $dir"
5735         local nums=$($cmd | wc -l)
5736
5737         [ $nums -eq $expected ] || {
5738                 $LFS getstripe -R $dir
5739                 error "'$cmd' wrong: found $nums, expected $expected"
5740         }
5741         rm -rf $dir
5742
5743         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5744
5745         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5746
5747         expected=$(((NUMDIRS + 1) * NUMFILES))
5748         cmd="$LFS find -stripe-size 512k -type f $dir"
5749         nums=$($cmd | wc -l)
5750         [ $nums -eq $expected ] ||
5751                 error "'$cmd' wrong: found $nums, expected $expected"
5752
5753         cmd="$LFS find -stripe-size +320k -type f $dir"
5754         nums=$($cmd | wc -l)
5755         [ $nums -eq $expected ] ||
5756                 error "'$cmd' wrong: found $nums, expected $expected"
5757
5758         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5759         cmd="$LFS find -stripe-size +200k -type f $dir"
5760         nums=$($cmd | wc -l)
5761         [ $nums -eq $expected ] ||
5762                 error "'$cmd' wrong: found $nums, expected $expected"
5763
5764         cmd="$LFS find -stripe-size -640k -type f $dir"
5765         nums=$($cmd | wc -l)
5766         [ $nums -eq $expected ] ||
5767                 error "'$cmd' wrong: found $nums, expected $expected"
5768
5769         expected=4
5770         cmd="$LFS find -stripe-size 256k -type f $dir"
5771         nums=$($cmd | wc -l)
5772         [ $nums -eq $expected ] ||
5773                 error "'$cmd' wrong: found $nums, expected $expected"
5774
5775         cmd="$LFS find -stripe-size -320k -type f $dir"
5776         nums=$($cmd | wc -l)
5777         [ $nums -eq $expected ] ||
5778                 error "'$cmd' wrong: found $nums, expected $expected"
5779
5780         expected=0
5781         cmd="$LFS find -stripe-size 1024k -type f $dir"
5782         nums=$($cmd | wc -l)
5783         [ $nums -eq $expected ] ||
5784                 error "'$cmd' wrong: found $nums, expected $expected"
5785 }
5786 run_test 56t "check lfs find -stripe-size works"
5787
5788 test_56u() { # LU-611
5789         local dir=$DIR/$tdir
5790
5791         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5792
5793         if [[ $OSTCOUNT -gt 1 ]]; then
5794                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5795                 onestripe=4
5796         else
5797                 onestripe=0
5798         fi
5799
5800         local expected=$(((NUMDIRS + 1) * NUMFILES))
5801         local cmd="$LFS find -stripe-index 0 -type f $dir"
5802         local nums=$($cmd | wc -l)
5803
5804         [ $nums -eq $expected ] ||
5805                 error "'$cmd' wrong: found $nums, expected $expected"
5806
5807         expected=$onestripe
5808         cmd="$LFS find -stripe-index 1 -type f $dir"
5809         nums=$($cmd | wc -l)
5810         [ $nums -eq $expected ] ||
5811                 error "'$cmd' wrong: found $nums, expected $expected"
5812
5813         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5814         nums=$($cmd | wc -l)
5815         [ $nums -eq $expected ] ||
5816                 error "'$cmd' wrong: found $nums, expected $expected"
5817
5818         expected=0
5819         # This should produce an error and not return any files
5820         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5821         nums=$($cmd 2>/dev/null | wc -l)
5822         [ $nums -eq $expected ] ||
5823                 error "'$cmd' wrong: found $nums, expected $expected"
5824
5825         if [[ $OSTCOUNT -gt 1 ]]; then
5826                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5827                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5828                 nums=$($cmd | wc -l)
5829                 [ $nums -eq $expected ] ||
5830                         error "'$cmd' wrong: found $nums, expected $expected"
5831         fi
5832 }
5833 run_test 56u "check lfs find -stripe-index works"
5834
5835 test_56v() {
5836         local mdt_idx=0
5837         local dir=$DIR/$tdir
5838
5839         setup_56 $dir $NUMFILES $NUMDIRS
5840
5841         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5842         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5843
5844         for file in $($LFS find -m $UUID $dir); do
5845                 file_midx=$($LFS getstripe -m $file)
5846                 [ $file_midx -eq $mdt_idx ] ||
5847                         error "lfs find -m $UUID != getstripe -m $file_midx"
5848         done
5849 }
5850 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5851
5852 test_56w() {
5853         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5854         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5855
5856         local dir=$DIR/$tdir
5857
5858         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5859
5860         local stripe_size=$($LFS getstripe -S -d $dir) ||
5861                 error "$LFS getstripe -S -d $dir failed"
5862         stripe_size=${stripe_size%% *}
5863
5864         local file_size=$((stripe_size * OSTCOUNT))
5865         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5866         local required_space=$((file_num * file_size))
5867         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5868                            head -n1)
5869         [[ $free_space -le $((required_space / 1024)) ]] &&
5870                 skip_env "need $required_space, have $free_space kbytes"
5871
5872         local dd_bs=65536
5873         local dd_count=$((file_size / dd_bs))
5874
5875         # write data into the files
5876         local i
5877         local j
5878         local file
5879
5880         for i in $(seq $NUMFILES); do
5881                 file=$dir/file$i
5882                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5883                         error "write data into $file failed"
5884         done
5885         for i in $(seq $NUMDIRS); do
5886                 for j in $(seq $NUMFILES); do
5887                         file=$dir/dir$i/file$j
5888                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5889                                 error "write data into $file failed"
5890                 done
5891         done
5892
5893         # $LFS_MIGRATE will fail if hard link migration is unsupported
5894         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5895                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5896                         error "creating links to $dir/dir1/file1 failed"
5897         fi
5898
5899         local expected=-1
5900
5901         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5902
5903         # lfs_migrate file
5904         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5905
5906         echo "$cmd"
5907         eval $cmd || error "$cmd failed"
5908
5909         check_stripe_count $dir/file1 $expected
5910
5911         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5912         then
5913                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5914                 # OST 1 if it is on OST 0. This file is small enough to
5915                 # be on only one stripe.
5916                 file=$dir/migr_1_ost
5917                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5918                         error "write data into $file failed"
5919                 local obdidx=$($LFS getstripe -i $file)
5920                 local oldmd5=$(md5sum $file)
5921                 local newobdidx=0
5922
5923                 [[ $obdidx -eq 0 ]] && newobdidx=1
5924                 cmd="$LFS migrate -i $newobdidx $file"
5925                 echo $cmd
5926                 eval $cmd || error "$cmd failed"
5927
5928                 local realobdix=$($LFS getstripe -i $file)
5929                 local newmd5=$(md5sum $file)
5930
5931                 [[ $newobdidx -ne $realobdix ]] &&
5932                         error "new OST is different (was=$obdidx, "\
5933                               "wanted=$newobdidx, got=$realobdix)"
5934                 [[ "$oldmd5" != "$newmd5" ]] &&
5935                         error "md5sum differ: $oldmd5, $newmd5"
5936         fi
5937
5938         # lfs_migrate dir
5939         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5940         echo "$cmd"
5941         eval $cmd || error "$cmd failed"
5942
5943         for j in $(seq $NUMFILES); do
5944                 check_stripe_count $dir/dir1/file$j $expected
5945         done
5946
5947         # lfs_migrate works with lfs find
5948         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5949              $LFS_MIGRATE -y -c $expected"
5950         echo "$cmd"
5951         eval $cmd || error "$cmd failed"
5952
5953         for i in $(seq 2 $NUMFILES); do
5954                 check_stripe_count $dir/file$i $expected
5955         done
5956         for i in $(seq 2 $NUMDIRS); do
5957                 for j in $(seq $NUMFILES); do
5958                 check_stripe_count $dir/dir$i/file$j $expected
5959                 done
5960         done
5961 }
5962 run_test 56w "check lfs_migrate -c stripe_count works"
5963
5964 test_56wb() {
5965         local file1=$DIR/$tdir/file1
5966         local create_pool=false
5967         local initial_pool=$($LFS getstripe -p $DIR)
5968         local pool_list=()
5969         local pool=""
5970
5971         echo -n "Creating test dir..."
5972         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5973         echo "done."
5974
5975         echo -n "Creating test file..."
5976         touch $file1 || error "cannot create file"
5977         echo "done."
5978
5979         echo -n "Detecting existing pools..."
5980         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
5981
5982         if [ ${#pool_list[@]} -gt 0 ]; then
5983                 echo "${pool_list[@]}"
5984                 for thispool in "${pool_list[@]}"; do
5985                         if [[ -z "$initial_pool" ||
5986                               "$initial_pool" != "$thispool" ]]; then
5987                                 pool="$thispool"
5988                                 echo "Using existing pool '$pool'"
5989                                 break
5990                         fi
5991                 done
5992         else
5993                 echo "none detected."
5994         fi
5995         if [ -z "$pool" ]; then
5996                 pool=${POOL:-testpool}
5997                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
5998                 echo -n "Creating pool '$pool'..."
5999                 create_pool=true
6000                 pool_add $pool &> /dev/null ||
6001                         error "pool_add failed"
6002                 echo "done."
6003
6004                 echo -n "Adding target to pool..."
6005                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6006                         error "pool_add_targets failed"
6007                 echo "done."
6008         fi
6009
6010         echo -n "Setting pool using -p option..."
6011         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6012                 error "migrate failed rc = $?"
6013         echo "done."
6014
6015         echo -n "Verifying test file is in pool after migrating..."
6016         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6017                 error "file was not migrated to pool $pool"
6018         echo "done."
6019
6020         echo -n "Removing test file from pool '$pool'..."
6021         $LFS migrate $file1 &> /dev/null ||
6022                 error "cannot remove from pool"
6023         [ "$($LFS getstripe -p $file1)" ] &&
6024                 error "pool still set"
6025         echo "done."
6026
6027         echo -n "Setting pool using --pool option..."
6028         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6029                 error "migrate failed rc = $?"
6030         echo "done."
6031
6032         # Clean up
6033         rm -f $file1
6034         if $create_pool; then
6035                 destroy_test_pools 2> /dev/null ||
6036                         error "destroy test pools failed"
6037         fi
6038 }
6039 run_test 56wb "check lfs_migrate pool support"
6040
6041 test_56wc() {
6042         local file1="$DIR/$tdir/file1"
6043
6044         echo -n "Creating test dir..."
6045         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6046         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6047         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6048                 error "cannot set stripe"
6049         echo "done"
6050
6051         echo -n "Setting initial stripe for test file..."
6052         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6053                 error "cannot set stripe"
6054         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6055                 error "stripe size not set"
6056         echo "done."
6057
6058         # File currently set to -S 512K -c 1
6059
6060         # Ensure -c and -S options are rejected when -R is set
6061         echo -n "Verifying incompatible options are detected..."
6062         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6063                 error "incompatible -c and -R options not detected"
6064         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6065                 error "incompatible -S and -R options not detected"
6066         echo "done."
6067
6068         # Ensure unrecognized options are passed through to 'lfs migrate'
6069         echo -n "Verifying -S option is passed through to lfs migrate..."
6070         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6071                 error "migration failed"
6072         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6073                 error "file was not restriped"
6074         echo "done."
6075
6076         # File currently set to -S 1M -c 1
6077
6078         # Ensure long options are supported
6079         echo -n "Verifying long options supported..."
6080         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6081                 error "long option without argument not supported"
6082         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6083                 error "long option with argument not supported"
6084         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6085                 error "file not restriped with --stripe-size option"
6086         echo "done."
6087
6088         # File currently set to -S 512K -c 1
6089
6090         if [ "$OSTCOUNT" -gt 1 ]; then
6091                 echo -n "Verifying explicit stripe count can be set..."
6092                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6093                         error "migrate failed"
6094                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6095                         error "file not restriped to explicit count"
6096                 echo "done."
6097         fi
6098
6099         # File currently set to -S 512K -c 1 or -S 512K -c 2
6100
6101         # Ensure parent striping is used if -R is set, and no stripe
6102         # count or size is specified
6103         echo -n "Setting stripe for parent directory..."
6104         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6105                 error "cannot set stripe"
6106         echo "done."
6107
6108         echo -n "Verifying restripe option uses parent stripe settings..."
6109         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6110                 error "migrate failed"
6111         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6112                 error "file not restriped to parent settings"
6113         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6114                 error "file not restriped to parent settings"
6115         echo "done."
6116
6117         # File currently set to -S 1M -c 1
6118
6119         # Ensure striping is preserved if -R is not set, and no stripe
6120         # count or size is specified
6121         echo -n "Verifying striping size preserved when not specified..."
6122         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6123         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6124                 error "cannot set stripe on parent directory"
6125         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6126                 error "migrate failed"
6127         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6128                 error "file was restriped"
6129         echo "done."
6130
6131         # Ensure file name properly detected when final option has no argument
6132         echo -n "Verifying file name properly detected..."
6133         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6134                 error "file name interpreted as option argument"
6135         echo "done."
6136
6137         # Clean up
6138         rm -f "$file1"
6139 }
6140 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6141
6142 test_56wd() {
6143         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6144
6145         local file1=$DIR/$tdir/file1
6146
6147         echo -n "Creating test dir..."
6148         test_mkdir $DIR/$tdir || error "cannot create dir"
6149         echo "done."
6150
6151         echo -n "Creating test file..."
6152         touch $file1
6153         echo "done."
6154
6155         # Ensure 'lfs migrate' will fail by using a non-existent option,
6156         # and make sure rsync is not called to recover
6157         echo -n "Make sure --no-rsync option works..."
6158         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6159                 grep -q 'refusing to fall back to rsync' ||
6160                 error "rsync was called with --no-rsync set"
6161         echo "done."
6162
6163         # Ensure rsync is called without trying 'lfs migrate' first
6164         echo -n "Make sure --rsync option works..."
6165         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6166                 grep -q 'falling back to rsync' &&
6167                 error "lfs migrate was called with --rsync set"
6168         echo "done."
6169
6170         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6171         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6172                 grep -q 'at the same time' ||
6173                 error "--rsync and --no-rsync accepted concurrently"
6174         echo "done."
6175
6176         # Clean up
6177         rm -f $file1
6178 }
6179 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6180
6181 test_56x() {
6182         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6183         check_swap_layouts_support
6184
6185         local dir=$DIR/$tdir
6186         local ref1=/etc/passwd
6187         local file1=$dir/file1
6188
6189         test_mkdir $dir || error "creating dir $dir"
6190         $LFS setstripe -c 2 $file1
6191         cp $ref1 $file1
6192         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6193         stripe=$($LFS getstripe -c $file1)
6194         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6195         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6196
6197         # clean up
6198         rm -f $file1
6199 }
6200 run_test 56x "lfs migration support"
6201
6202 test_56xa() {
6203         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6204         check_swap_layouts_support
6205
6206         local dir=$DIR/$tdir/$testnum
6207
6208         test_mkdir -p $dir
6209
6210         local ref1=/etc/passwd
6211         local file1=$dir/file1
6212
6213         $LFS setstripe -c 2 $file1
6214         cp $ref1 $file1
6215         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6216
6217         local stripe=$($LFS getstripe -c $file1)
6218
6219         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6220         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6221
6222         # clean up
6223         rm -f $file1
6224 }
6225 run_test 56xa "lfs migration --block support"
6226
6227 check_migrate_links() {
6228         local dir="$1"
6229         local file1="$dir/file1"
6230         local begin="$2"
6231         local count="$3"
6232         local total_count=$(($begin + $count - 1))
6233         local symlink_count=10
6234         local uniq_count=10
6235
6236         if [ ! -f "$file1" ]; then
6237                 echo -n "creating initial file..."
6238                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6239                         error "cannot setstripe initial file"
6240                 echo "done"
6241
6242                 echo -n "creating symlinks..."
6243                 for s in $(seq 1 $symlink_count); do
6244                         ln -s "$file1" "$dir/slink$s" ||
6245                                 error "cannot create symlinks"
6246                 done
6247                 echo "done"
6248
6249                 echo -n "creating nonlinked files..."
6250                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6251                         error "cannot create nonlinked files"
6252                 echo "done"
6253         fi
6254
6255         # create hard links
6256         if [ ! -f "$dir/file$total_count" ]; then
6257                 echo -n "creating hard links $begin:$total_count..."
6258                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6259                         /dev/null || error "cannot create hard links"
6260                 echo "done"
6261         fi
6262
6263         echo -n "checking number of hard links listed in xattrs..."
6264         local fid=$($LFS getstripe -F "$file1")
6265         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6266
6267         echo "${#paths[*]}"
6268         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6269                         skip "hard link list has unexpected size, skipping test"
6270         fi
6271         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6272                         error "link names should exceed xattrs size"
6273         fi
6274
6275         echo -n "migrating files..."
6276         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6277         local rc=$?
6278         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6279         echo "done"
6280
6281         # make sure all links have been properly migrated
6282         echo -n "verifying files..."
6283         fid=$($LFS getstripe -F "$file1") ||
6284                 error "cannot get fid for file $file1"
6285         for i in $(seq 2 $total_count); do
6286                 local fid2=$($LFS getstripe -F $dir/file$i)
6287
6288                 [ "$fid2" == "$fid" ] ||
6289                         error "migrated hard link has mismatched FID"
6290         done
6291
6292         # make sure hard links were properly detected, and migration was
6293         # performed only once for the entire link set; nonlinked files should
6294         # also be migrated
6295         local actual=$(grep -c 'done migrate' <<< "$migrate_out")
6296         local expected=$(($uniq_count + 1))
6297
6298         [ "$actual" -eq  "$expected" ] ||
6299                 error "hard links individually migrated ($actual != $expected)"
6300
6301         # make sure the correct number of hard links are present
6302         local hardlinks=$(stat -c '%h' "$file1")
6303
6304         [ $hardlinks -eq $total_count ] ||
6305                 error "num hard links $hardlinks != $total_count"
6306         echo "done"
6307
6308         return 0
6309 }
6310
6311 test_56xb() {
6312         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6313                 skip "Need MDS version at least 2.10.55"
6314
6315         local dir="$DIR/$tdir"
6316
6317         test_mkdir "$dir" || error "cannot create dir $dir"
6318
6319         echo "testing lfs migrate mode when all links fit within xattrs"
6320         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6321
6322         echo "testing rsync mode when all links fit within xattrs"
6323         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6324
6325         echo "testing lfs migrate mode when all links do not fit within xattrs"
6326         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6327
6328         echo "testing rsync mode when all links do not fit within xattrs"
6329         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6330
6331
6332         # clean up
6333         rm -rf $dir
6334 }
6335 run_test 56xb "lfs migration hard link support"
6336
6337 test_56xc() {
6338         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6339
6340         local dir="$DIR/$tdir"
6341
6342         test_mkdir "$dir" || error "cannot create dir $dir"
6343
6344         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6345         echo -n "Setting initial stripe for 20MB test file..."
6346         $LFS setstripe -c 2 -i 0 "$dir/20mb" || error "cannot setstripe"
6347         echo "done"
6348         echo -n "Sizing 20MB test file..."
6349         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6350         echo "done"
6351         echo -n "Verifying small file autostripe count is 1..."
6352         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" &> /dev/null ||
6353                 error "cannot migrate 20MB file"
6354         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6355                 error "cannot get stripe for $dir/20mb"
6356         [ $stripe_count -eq 1 ] ||
6357                 error "unexpected stripe count $stripe_count for 20MB file"
6358         rm -f "$dir/20mb"
6359         echo "done"
6360
6361         # Test 2: File is small enough to fit within the available space on
6362         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6363         # have at least an additional 1KB for each desired stripe for test 3
6364         echo -n "Setting stripe for 1GB test file..."
6365         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe"
6366         echo "done"
6367         echo -n "Sizing 1GB test file..."
6368         # File size is 1GB + 3KB
6369         truncate "$dir/1gb" 1073744896 &> /dev/null ||
6370                 error "cannot create 1GB test file"
6371         echo "done"
6372         echo -n "Migrating 1GB file..."
6373         $LFS_MIGRATE -y -A -C 1 "$dir/1gb" &> /dev/null ||
6374                 error "cannot migrate file"
6375         echo "done"
6376         echo -n "Verifying autostripe count is sqrt(n) + 1..."
6377         stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6378                 error "cannot get stripe for $dir/1gb"
6379         [ $stripe_count -eq 2 ] ||
6380                 error "unexpected stripe count $stripe_count (expected 2)"
6381         echo "done"
6382
6383         # Test 3: File is too large to fit within the available space on
6384         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6385         if [ $OSTCOUNT -ge 3 ]; then
6386                 # The required available space is calculated as
6387                 # file size (1GB + 3KB) / OST count (3).
6388                 local kb_per_ost=349526
6389
6390                 echo -n "Migrating 1GB file..."
6391                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" &>> \
6392                         /dev/null || error "cannot migrate file"
6393                 echo "done"
6394
6395                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6396                 echo -n "Verifying autostripe count with limited space..."
6397                 [ "$stripe_count" -a $stripe_count -eq 3 ] ||
6398                         error "unexpected stripe count $stripe_count (wanted 3)"
6399                 echo "done"
6400         fi
6401
6402         # clean up
6403         rm -rf $dir
6404 }
6405 run_test 56xc "lfs migration autostripe"
6406
6407 test_56y() {
6408         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6409                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6410
6411         local res=""
6412         local dir=$DIR/$tdir
6413         local f1=$dir/file1
6414         local f2=$dir/file2
6415
6416         test_mkdir -p $dir || error "creating dir $dir"
6417         touch $f1 || error "creating std file $f1"
6418         $MULTIOP $f2 H2c || error "creating released file $f2"
6419
6420         # a directory can be raid0, so ask only for files
6421         res=$($LFS find $dir -L raid0 -type f | wc -l)
6422         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6423
6424         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6425         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6426
6427         # only files can be released, so no need to force file search
6428         res=$($LFS find $dir -L released)
6429         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6430
6431         res=$($LFS find $dir -type f \! -L released)
6432         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6433 }
6434 run_test 56y "lfs find -L raid0|released"
6435
6436 test_56z() { # LU-4824
6437         # This checks to make sure 'lfs find' continues after errors
6438         # There are two classes of errors that should be caught:
6439         # - If multiple paths are provided, all should be searched even if one
6440         #   errors out
6441         # - If errors are encountered during the search, it should not terminate
6442         #   early
6443         local dir=$DIR/$tdir
6444         local i
6445
6446         test_mkdir $dir
6447         for i in d{0..9}; do
6448                 test_mkdir $dir/$i
6449         done
6450         touch $dir/d{0..9}/$tfile
6451         $LFS find $DIR/non_existent_dir $dir &&
6452                 error "$LFS find did not return an error"
6453         # Make a directory unsearchable. This should NOT be the last entry in
6454         # directory order.  Arbitrarily pick the 6th entry
6455         chmod 700 $($LFS find $dir -type d | sed '6!d')
6456
6457         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6458
6459         # The user should be able to see 10 directories and 9 files
6460         [ $count == 19 ] || error "$LFS find did not continue after error"
6461 }
6462 run_test 56z "lfs find should continue after an error"
6463
6464 test_56aa() { # LU-5937
6465         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6466
6467         local dir=$DIR/$tdir
6468
6469         mkdir $dir
6470         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6471
6472         createmany -o $dir/striped_dir/${tfile}- 1024
6473         local dirs=$($LFS find --size +8k $dir/)
6474
6475         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6476 }
6477 run_test 56aa "lfs find --size under striped dir"
6478
6479 test_56ab() { # LU-10705
6480         test_mkdir $DIR/$tdir
6481         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6482         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6483         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6484         # Flush writes to ensure valid blocks.  Need to be more thorough for
6485         # ZFS, since blocks are not allocated/returned to client immediately.
6486         sync_all_data
6487         wait_zfs_commit ost1 2
6488         cancel_lru_locks osc
6489         ls -ls $DIR/$tdir
6490
6491         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6492
6493         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6494
6495         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6496         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6497
6498         rm -f $DIR/$tdir/$tfile.[123]
6499 }
6500 run_test 56ab "lfs find --blocks"
6501
6502 test_56ba() {
6503         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6504                 skip "Need MDS version at least 2.10.50"
6505
6506         # Create composite files with one component
6507         local dir=$DIR/$tdir
6508
6509         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6510         # Create composite files with three components
6511         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6512         # Create non-composite files
6513         createmany -o $dir/${tfile}- 10
6514
6515         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6516
6517         [[ $nfiles == 10 ]] ||
6518                 error "lfs find -E 1M found $nfiles != 10 files"
6519
6520         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6521         [[ $nfiles == 25 ]] ||
6522                 error "lfs find ! -E 1M found $nfiles != 25 files"
6523
6524         # All files have a component that starts at 0
6525         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6526         [[ $nfiles == 35 ]] ||
6527                 error "lfs find --component-start 0 - $nfiles != 35 files"
6528
6529         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6530         [[ $nfiles == 15 ]] ||
6531                 error "lfs find --component-start 2M - $nfiles != 15 files"
6532
6533         # All files created here have a componenet that does not starts at 2M
6534         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6535         [[ $nfiles == 35 ]] ||
6536                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6537
6538         # Find files with a specified number of components
6539         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6540         [[ $nfiles == 15 ]] ||
6541                 error "lfs find --component-count 3 - $nfiles != 15 files"
6542
6543         # Remember non-composite files have a component count of zero
6544         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6545         [[ $nfiles == 10 ]] ||
6546                 error "lfs find --component-count 0 - $nfiles != 10 files"
6547
6548         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6549         [[ $nfiles == 20 ]] ||
6550                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6551
6552         # All files have a flag called "init"
6553         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6554         [[ $nfiles == 35 ]] ||
6555                 error "lfs find --component-flags init - $nfiles != 35 files"
6556
6557         # Multi-component files will have a component not initialized
6558         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6559         [[ $nfiles == 15 ]] ||
6560                 error "lfs find !--component-flags init - $nfiles != 15 files"
6561
6562         rm -rf $dir
6563
6564 }
6565 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6566
6567 test_56ca() {
6568         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6569                 skip "Need MDS version at least 2.10.57"
6570
6571         local td=$DIR/$tdir
6572         local tf=$td/$tfile
6573         local dir
6574         local nfiles
6575         local cmd
6576         local i
6577         local j
6578
6579         # create mirrored directories and mirrored files
6580         mkdir $td || error "mkdir $td failed"
6581         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6582         createmany -o $tf- 10 || error "create $tf- failed"
6583
6584         for i in $(seq 2); do
6585                 dir=$td/dir$i
6586                 mkdir $dir || error "mkdir $dir failed"
6587                 $LFS mirror create -N$((3 + i)) $dir ||
6588                         error "create mirrored dir $dir failed"
6589                 createmany -o $dir/$tfile- 10 ||
6590                         error "create $dir/$tfile- failed"
6591         done
6592
6593         # change the states of some mirrored files
6594         echo foo > $tf-6
6595         for i in $(seq 2); do
6596                 dir=$td/dir$i
6597                 for j in $(seq 4 9); do
6598                         echo foo > $dir/$tfile-$j
6599                 done
6600         done
6601
6602         # find mirrored files with specific mirror count
6603         cmd="$LFS find --mirror-count 3 --type f $td"
6604         nfiles=$($cmd | wc -l)
6605         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6606
6607         cmd="$LFS find ! --mirror-count 3 --type f $td"
6608         nfiles=$($cmd | wc -l)
6609         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6610
6611         cmd="$LFS find --mirror-count +2 --type f $td"
6612         nfiles=$($cmd | wc -l)
6613         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6614
6615         cmd="$LFS find --mirror-count -6 --type f $td"
6616         nfiles=$($cmd | wc -l)
6617         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6618
6619         # find mirrored files with specific file state
6620         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6621         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6622
6623         cmd="$LFS find --mirror-state=ro --type f $td"
6624         nfiles=$($cmd | wc -l)
6625         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6626
6627         cmd="$LFS find ! --mirror-state=ro --type f $td"
6628         nfiles=$($cmd | wc -l)
6629         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6630
6631         cmd="$LFS find --mirror-state=wp --type f $td"
6632         nfiles=$($cmd | wc -l)
6633         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6634
6635         cmd="$LFS find ! --mirror-state=sp --type f $td"
6636         nfiles=$($cmd | wc -l)
6637         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6638 }
6639 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6640
6641 test_57a() {
6642         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6643         # note test will not do anything if MDS is not local
6644         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6645                 skip_env "ldiskfs only test"
6646         fi
6647         remote_mds_nodsh && skip "remote MDS with nodsh"
6648
6649         local MNTDEV="osd*.*MDT*.mntdev"
6650         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6651         [ -z "$DEV" ] && error "can't access $MNTDEV"
6652         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6653                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6654                         error "can't access $DEV"
6655                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6656                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6657                 rm $TMP/t57a.dump
6658         done
6659 }
6660 run_test 57a "verify MDS filesystem created with large inodes =="
6661
6662 test_57b() {
6663         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6664         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6665                 skip_env "ldiskfs only test"
6666         fi
6667         remote_mds_nodsh && skip "remote MDS with nodsh"
6668
6669         local dir=$DIR/$tdir
6670         local filecount=100
6671         local file1=$dir/f1
6672         local fileN=$dir/f$filecount
6673
6674         rm -rf $dir || error "removing $dir"
6675         test_mkdir -c1 $dir
6676         local mdtidx=$($LFS getstripe -m $dir)
6677         local mdtname=MDT$(printf %04x $mdtidx)
6678         local facet=mds$((mdtidx + 1))
6679
6680         echo "mcreating $filecount files"
6681         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6682
6683         # verify that files do not have EAs yet
6684         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6685                 error "$file1 has an EA"
6686         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6687                 error "$fileN has an EA"
6688
6689         sync
6690         sleep 1
6691         df $dir  #make sure we get new statfs data
6692         local mdsfree=$(do_facet $facet \
6693                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6694         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6695         local file
6696
6697         echo "opening files to create objects/EAs"
6698         for file in $(seq -f $dir/f%g 1 $filecount); do
6699                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6700                         error "opening $file"
6701         done
6702
6703         # verify that files have EAs now
6704         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6705         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6706
6707         sleep 1  #make sure we get new statfs data
6708         df $dir
6709         local mdsfree2=$(do_facet $facet \
6710                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6711         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6712
6713         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6714                 if [ "$mdsfree" != "$mdsfree2" ]; then
6715                         error "MDC before $mdcfree != after $mdcfree2"
6716                 else
6717                         echo "MDC before $mdcfree != after $mdcfree2"
6718                         echo "unable to confirm if MDS has large inodes"
6719                 fi
6720         fi
6721         rm -rf $dir
6722 }
6723 run_test 57b "default LOV EAs are stored inside large inodes ==="
6724
6725 test_58() {
6726         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6727         [ -z "$(which wiretest 2>/dev/null)" ] &&
6728                         skip_env "could not find wiretest"
6729
6730         wiretest
6731 }
6732 run_test 58 "verify cross-platform wire constants =============="
6733
6734 test_59() {
6735         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6736
6737         echo "touch 130 files"
6738         createmany -o $DIR/f59- 130
6739         echo "rm 130 files"
6740         unlinkmany $DIR/f59- 130
6741         sync
6742         # wait for commitment of removal
6743         wait_delete_completed
6744 }
6745 run_test 59 "verify cancellation of llog records async ========="
6746
6747 TEST60_HEAD="test_60 run $RANDOM"
6748 test_60a() {
6749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6750         remote_mgs_nodsh && skip "remote MGS with nodsh"
6751         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6752                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6753                         skip_env "missing subtest run-llog.sh"
6754
6755         log "$TEST60_HEAD - from kernel mode"
6756         do_facet mgs "$LCTL dk > /dev/null"
6757         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6758         do_facet mgs $LCTL dk > $TMP/$tfile
6759
6760         # LU-6388: test llog_reader
6761         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6762         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6763         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6764                         skip_env "missing llog_reader"
6765         local fstype=$(facet_fstype mgs)
6766         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6767                 skip_env "Only for ldiskfs or zfs type mgs"
6768
6769         local mntpt=$(facet_mntpt mgs)
6770         local mgsdev=$(mgsdevname 1)
6771         local fid_list
6772         local fid
6773         local rec_list
6774         local rec
6775         local rec_type
6776         local obj_file
6777         local path
6778         local seq
6779         local oid
6780         local pass=true
6781
6782         #get fid and record list
6783         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6784                 tail -n 4))
6785         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6786                 tail -n 4))
6787         #remount mgs as ldiskfs or zfs type
6788         stop mgs || error "stop mgs failed"
6789         mount_fstype mgs || error "remount mgs failed"
6790         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6791                 fid=${fid_list[i]}
6792                 rec=${rec_list[i]}
6793                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6794                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6795                 oid=$((16#$oid))
6796
6797                 case $fstype in
6798                         ldiskfs )
6799                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6800                         zfs )
6801                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6802                 esac
6803                 echo "obj_file is $obj_file"
6804                 do_facet mgs $llog_reader $obj_file
6805
6806                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6807                         awk '{ print $3 }' | sed -e "s/^type=//g")
6808                 if [ $rec_type != $rec ]; then
6809                         echo "FAILED test_60a wrong record type $rec_type," \
6810                               "should be $rec"
6811                         pass=false
6812                         break
6813                 fi
6814
6815                 #check obj path if record type is LLOG_LOGID_MAGIC
6816                 if [ "$rec" == "1064553b" ]; then
6817                         path=$(do_facet mgs $llog_reader $obj_file |
6818                                 grep "path=" | awk '{ print $NF }' |
6819                                 sed -e "s/^path=//g")
6820                         if [ $obj_file != $mntpt/$path ]; then
6821                                 echo "FAILED test_60a wrong obj path" \
6822                                       "$montpt/$path, should be $obj_file"
6823                                 pass=false
6824                                 break
6825                         fi
6826                 fi
6827         done
6828         rm -f $TMP/$tfile
6829         #restart mgs before "error", otherwise it will block the next test
6830         stop mgs || error "stop mgs failed"
6831         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6832         $pass || error "test failed, see FAILED test_60a messages for specifics"
6833 }
6834 run_test 60a "llog_test run from kernel module and test llog_reader"
6835
6836 test_60b() { # bug 6411
6837         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6838
6839         dmesg > $DIR/$tfile
6840         LLOG_COUNT=$(do_facet mgs dmesg |
6841                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6842                           /llog_[a-z]*.c:[0-9]/ {
6843                                 if (marker)
6844                                         from_marker++
6845                                 from_begin++
6846                           }
6847                           END {
6848                                 if (marker)
6849                                         print from_marker
6850                                 else
6851                                         print from_begin
6852                           }")
6853
6854         [[ $LLOG_COUNT -gt 120 ]] &&
6855                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6856 }
6857 run_test 60b "limit repeated messages from CERROR/CWARN"
6858
6859 test_60c() {
6860         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6861
6862         echo "create 5000 files"
6863         createmany -o $DIR/f60c- 5000
6864 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6865         lctl set_param fail_loc=0x80000137
6866         unlinkmany $DIR/f60c- 5000
6867         lctl set_param fail_loc=0
6868 }
6869 run_test 60c "unlink file when mds full"
6870
6871 test_60d() {
6872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6873
6874         SAVEPRINTK=$(lctl get_param -n printk)
6875         # verify "lctl mark" is even working"
6876         MESSAGE="test message ID $RANDOM $$"
6877         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6878         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6879
6880         lctl set_param printk=0 || error "set lnet.printk failed"
6881         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6882         MESSAGE="new test message ID $RANDOM $$"
6883         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6884         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6885         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6886
6887         lctl set_param -n printk="$SAVEPRINTK"
6888 }
6889 run_test 60d "test printk console message masking"
6890
6891 test_60e() {
6892         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6893         remote_mds_nodsh && skip "remote MDS with nodsh"
6894
6895         touch $DIR/$tfile
6896 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6897         do_facet mds1 lctl set_param fail_loc=0x15b
6898         rm $DIR/$tfile
6899 }
6900 run_test 60e "no space while new llog is being created"
6901
6902 test_60g() {
6903         local pid
6904
6905         test_mkdir -c $MDSCOUNT $DIR/$tdir
6906         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6907
6908         (
6909                 local index=0
6910                 while true; do
6911                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6912                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6913                         index=$((index + 1))
6914                 done
6915         ) &
6916
6917         pid=$!
6918
6919         for i in $(seq 100); do 
6920                 # define OBD_FAIL_OSD_TXN_START    0x19a
6921                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6922                 usleep 100
6923         done
6924
6925         kill -9 $pid
6926
6927         mkdir $DIR/$tdir/new || error "mkdir failed"
6928         rmdir $DIR/$tdir/new || error "rmdir failed"
6929 }
6930 run_test 60g "transaction abort won't cause MDT hung"
6931
6932 test_60h() {
6933         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6934                 skip "Need MDS version at least 2.12.52"
6935         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6936
6937         local f
6938
6939         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6940         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6941         for fail_loc in 0x80000188 0x80000189; do
6942                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6943                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6944                         error "mkdir $dir-$fail_loc failed"
6945                 for i in {0..10}; do
6946                         # create may fail on missing stripe
6947                         echo $i > $DIR/$tdir-$fail_loc/$i
6948                 done
6949                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6950                         error "getdirstripe $tdir-$fail_loc failed"
6951                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6952                         error "migrate $tdir-$fail_loc failed"
6953                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6954                         error "getdirstripe $tdir-$fail_loc failed"
6955                 pushd $DIR/$tdir-$fail_loc
6956                 for f in *; do
6957                         echo $f | cmp $f - || error "$f data mismatch"
6958                 done
6959                 popd
6960                 rm -rf $DIR/$tdir-$fail_loc
6961         done
6962 }
6963 run_test 60h "striped directory with missing stripes can be accessed"
6964
6965 test_61a() {
6966         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6967
6968         f="$DIR/f61"
6969         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6970         cancel_lru_locks osc
6971         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6972         sync
6973 }
6974 run_test 61a "mmap() writes don't make sync hang ================"
6975
6976 test_61b() {
6977         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
6978 }
6979 run_test 61b "mmap() of unstriped file is successful"
6980
6981 # bug 2330 - insufficient obd_match error checking causes LBUG
6982 test_62() {
6983         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6984
6985         f="$DIR/f62"
6986         echo foo > $f
6987         cancel_lru_locks osc
6988         lctl set_param fail_loc=0x405
6989         cat $f && error "cat succeeded, expect -EIO"
6990         lctl set_param fail_loc=0
6991 }
6992 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
6993 # match every page all of the time.
6994 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
6995
6996 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
6997 # Though this test is irrelevant anymore, it helped to reveal some
6998 # other grant bugs (LU-4482), let's keep it.
6999 test_63a() {   # was test_63
7000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7001
7002         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7003
7004         for i in `seq 10` ; do
7005                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7006                 sleep 5
7007                 kill $!
7008                 sleep 1
7009         done
7010
7011         rm -f $DIR/f63 || true
7012 }
7013 run_test 63a "Verify oig_wait interruption does not crash ======="
7014
7015 # bug 2248 - async write errors didn't return to application on sync
7016 # bug 3677 - async write errors left page locked
7017 test_63b() {
7018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7019
7020         debugsave
7021         lctl set_param debug=-1
7022
7023         # ensure we have a grant to do async writes
7024         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7025         rm $DIR/$tfile
7026
7027         sync    # sync lest earlier test intercept the fail_loc
7028
7029         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7030         lctl set_param fail_loc=0x80000406
7031         $MULTIOP $DIR/$tfile Owy && \
7032                 error "sync didn't return ENOMEM"
7033         sync; sleep 2; sync     # do a real sync this time to flush page
7034         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7035                 error "locked page left in cache after async error" || true
7036         debugrestore
7037 }
7038 run_test 63b "async write errors should be returned to fsync ==="
7039
7040 test_64a () {
7041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7042
7043         df $DIR
7044         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7045 }
7046 run_test 64a "verify filter grant calculations (in kernel) ====="
7047
7048 test_64b () {
7049         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7050
7051         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7052 }
7053 run_test 64b "check out-of-space detection on client"
7054
7055 test_64c() {
7056         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7057 }
7058 run_test 64c "verify grant shrink"
7059
7060 # this does exactly what osc_request.c:osc_announce_cached() does in
7061 # order to calculate max amount of grants to ask from server
7062 want_grant() {
7063         local tgt=$1
7064
7065         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7066         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7067
7068         ((rpc_in_flight ++));
7069         nrpages=$((nrpages * rpc_in_flight))
7070
7071         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7072
7073         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7074
7075         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7076         local undirty=$((nrpages * PAGE_SIZE))
7077
7078         local max_extent_pages
7079         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7080             grep grant_max_extent_size | awk '{print $2}')
7081         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7082         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7083         local grant_extent_tax
7084         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7085             grep grant_extent_tax | awk '{print $2}')
7086
7087         undirty=$((undirty + nrextents * grant_extent_tax))
7088
7089         echo $undirty
7090 }
7091
7092 # this is size of unit for grant allocation. It should be equal to
7093 # what tgt_grant.c:tgt_grant_chunk() calculates
7094 grant_chunk() {
7095         local tgt=$1
7096         local max_brw_size
7097         local grant_extent_tax
7098
7099         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7100             grep max_brw_size | awk '{print $2}')
7101
7102         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7103             grep grant_extent_tax | awk '{print $2}')
7104
7105         echo $(((max_brw_size + grant_extent_tax) * 2))
7106 }
7107
7108 test_64d() {
7109         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7110                 skip "OST < 2.10.55 doesn't limit grants enough"
7111
7112         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7113         local file=$DIR/$tfile
7114
7115         [[ $($LCTL get_param osc.${tgt}.import |
7116              grep "connect_flags:.*grant_param") ]] ||
7117                 skip "no grant_param connect flag"
7118
7119         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7120
7121         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7122
7123         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7124         stack_trap "rm -f $file" EXIT
7125
7126         $LFS setstripe $file -i 0 -c 1
7127         dd if=/dev/zero of=$file bs=1M count=1000 &
7128         ddpid=$!
7129
7130         while true
7131         do
7132                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7133                 if [[ $cur_grant -gt $max_cur_granted ]]
7134                 then
7135                         kill $ddpid
7136                         error "cur_grant $cur_grant > $max_cur_granted"
7137                 fi
7138                 kill -0 $ddpid
7139                 [[ $? -ne 0 ]] && break;
7140                 sleep 2
7141         done
7142
7143         rm -f $DIR/$tfile
7144         wait_delete_completed
7145         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7146 }
7147 run_test 64d "check grant limit exceed"
7148
7149 # bug 1414 - set/get directories' stripe info
7150 test_65a() {
7151         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7152
7153         test_mkdir $DIR/$tdir
7154         touch $DIR/$tdir/f1
7155         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7156 }
7157 run_test 65a "directory with no stripe info"
7158
7159 test_65b() {
7160         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7161
7162         test_mkdir $DIR/$tdir
7163         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7164
7165         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7166                                                 error "setstripe"
7167         touch $DIR/$tdir/f2
7168         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7169 }
7170 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7171
7172 test_65c() {
7173         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7174         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7175
7176         test_mkdir $DIR/$tdir
7177         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7178
7179         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7180                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7181         touch $DIR/$tdir/f3
7182         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7183 }
7184 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7185
7186 test_65d() {
7187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7188
7189         test_mkdir $DIR/$tdir
7190         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7191         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7192
7193         if [[ $STRIPECOUNT -le 0 ]]; then
7194                 sc=1
7195         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7196                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7197                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7198         else
7199                 sc=$(($STRIPECOUNT - 1))
7200         fi
7201         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7202         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7203         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7204                 error "lverify failed"
7205 }
7206 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7207
7208 test_65e() {
7209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7210
7211         test_mkdir $DIR/$tdir
7212
7213         $LFS setstripe $DIR/$tdir || error "setstripe"
7214         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7215                                         error "no stripe info failed"
7216         touch $DIR/$tdir/f6
7217         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7218 }
7219 run_test 65e "directory setstripe defaults"
7220
7221 test_65f() {
7222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7223
7224         test_mkdir $DIR/${tdir}f
7225         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7226                 error "setstripe succeeded" || true
7227 }
7228 run_test 65f "dir setstripe permission (should return error) ==="
7229
7230 test_65g() {
7231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7232
7233         test_mkdir $DIR/$tdir
7234         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7235
7236         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7237                 error "setstripe -S failed"
7238         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7239         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7240                 error "delete default stripe failed"
7241 }
7242 run_test 65g "directory setstripe -d"
7243
7244 test_65h() {
7245         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7246
7247         test_mkdir $DIR/$tdir
7248         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7249
7250         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7251                 error "setstripe -S failed"
7252         test_mkdir $DIR/$tdir/dd1
7253         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7254                 error "stripe info inherit failed"
7255 }
7256 run_test 65h "directory stripe info inherit ===================="
7257
7258 test_65i() {
7259         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7260
7261         save_layout_restore_at_exit $MOUNT
7262
7263         # bug6367: set non-default striping on root directory
7264         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7265
7266         # bug12836: getstripe on -1 default directory striping
7267         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7268
7269         # bug12836: getstripe -v on -1 default directory striping
7270         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7271
7272         # bug12836: new find on -1 default directory striping
7273         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7274 }
7275 run_test 65i "various tests to set root directory striping"
7276
7277 test_65j() { # bug6367
7278         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7279
7280         sync; sleep 1
7281
7282         # if we aren't already remounting for each test, do so for this test
7283         if [ "$I_MOUNTED" = "yes" ]; then
7284                 cleanup || error "failed to unmount"
7285                 setup
7286         fi
7287
7288         save_layout_restore_at_exit $MOUNT
7289
7290         $LFS setstripe -d $MOUNT || error "setstripe failed"
7291 }
7292 run_test 65j "set default striping on root directory (bug 6367)="
7293
7294 cleanup_65k() {
7295         rm -rf $DIR/$tdir
7296         wait_delete_completed
7297         do_facet $SINGLEMDS "lctl set_param -n \
7298                 osp.$ost*MDT0000.max_create_count=$max_count"
7299         do_facet $SINGLEMDS "lctl set_param -n \
7300                 osp.$ost*MDT0000.create_count=$count"
7301         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7302         echo $INACTIVE_OSC "is Activate"
7303
7304         wait_osc_import_state mds ost$ostnum FULL
7305 }
7306
7307 test_65k() { # bug11679
7308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7309         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7310         remote_mds_nodsh && skip "remote MDS with nodsh"
7311
7312         local disable_precreate=true
7313         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7314                 disable_precreate=false
7315
7316         echo "Check OST status: "
7317         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7318                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7319
7320         for OSC in $MDS_OSCS; do
7321                 echo $OSC "is active"
7322                 do_facet $SINGLEMDS lctl --device %$OSC activate
7323         done
7324
7325         for INACTIVE_OSC in $MDS_OSCS; do
7326                 local ost=$(osc_to_ost $INACTIVE_OSC)
7327                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7328                                lov.*md*.target_obd |
7329                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7330
7331                 mkdir -p $DIR/$tdir
7332                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7333                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7334
7335                 echo "Deactivate: " $INACTIVE_OSC
7336                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7337
7338                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7339                               osp.$ost*MDT0000.create_count")
7340                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7341                                   osp.$ost*MDT0000.max_create_count")
7342                 $disable_precreate &&
7343                         do_facet $SINGLEMDS "lctl set_param -n \
7344                                 osp.$ost*MDT0000.max_create_count=0"
7345
7346                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7347                         [ -f $DIR/$tdir/$idx ] && continue
7348                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7349                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7350                                 { cleanup_65k;
7351                                   error "setstripe $idx should succeed"; }
7352                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7353                 done
7354                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7355                 rmdir $DIR/$tdir
7356
7357                 do_facet $SINGLEMDS "lctl set_param -n \
7358                         osp.$ost*MDT0000.max_create_count=$max_count"
7359                 do_facet $SINGLEMDS "lctl set_param -n \
7360                         osp.$ost*MDT0000.create_count=$count"
7361                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7362                 echo $INACTIVE_OSC "is Activate"
7363
7364                 wait_osc_import_state mds ost$ostnum FULL
7365         done
7366 }
7367 run_test 65k "validate manual striping works properly with deactivated OSCs"
7368
7369 test_65l() { # bug 12836
7370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7371
7372         test_mkdir -p $DIR/$tdir/test_dir
7373         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7374         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7375 }
7376 run_test 65l "lfs find on -1 stripe dir ========================"
7377
7378 test_65m() {
7379         local layout=$(save_layout $MOUNT)
7380         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7381                 restore_layout $MOUNT $layout
7382                 error "setstripe should fail by non-root users"
7383         }
7384         true
7385 }
7386 run_test 65m "normal user can't set filesystem default stripe"
7387
7388 test_65n() {
7389         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7390         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7391                 skip "Need MDS version at least 2.12.50"
7392         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7393
7394         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7395         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7396         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7397
7398         local root_layout=$(save_layout $MOUNT)
7399         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7400
7401         # new subdirectory under root directory should not inherit
7402         # the default layout from root
7403         local dir1=$MOUNT/$tdir-1
7404         mkdir $dir1 || error "mkdir $dir1 failed"
7405         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7406                 error "$dir1 shouldn't have LOV EA"
7407
7408         # delete the default layout on root directory
7409         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7410
7411         local dir2=$MOUNT/$tdir-2
7412         mkdir $dir2 || error "mkdir $dir2 failed"
7413         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7414                 error "$dir2 shouldn't have LOV EA"
7415
7416         # set a new striping pattern on root directory
7417         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7418         local new_def_stripe_size=$((def_stripe_size * 2))
7419         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7420                 error "set stripe size on $MOUNT failed"
7421
7422         # new file created in $dir2 should inherit the new stripe size from
7423         # the filesystem default
7424         local file2=$dir2/$tfile-2
7425         touch $file2 || error "touch $file2 failed"
7426
7427         local file2_stripe_size=$($LFS getstripe -S $file2)
7428         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7429                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7430
7431         local dir3=$MOUNT/$tdir-3
7432         mkdir $dir3 || error "mkdir $dir3 failed"
7433         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7434                 error "$dir3 shouldn't have LOV EA"
7435
7436         # set OST pool on root directory
7437         local pool=$TESTNAME
7438         pool_add $pool || error "add $pool failed"
7439         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7440                 error "add targets to $pool failed"
7441
7442         $LFS setstripe -p $pool $MOUNT ||
7443                 error "set OST pool on $MOUNT failed"
7444
7445         # new file created in $dir3 should inherit the pool from
7446         # the filesystem default
7447         local file3=$dir3/$tfile-3
7448         touch $file3 || error "touch $file3 failed"
7449
7450         local file3_pool=$($LFS getstripe -p $file3)
7451         [[ "$file3_pool" = "$pool" ]] ||
7452                 error "$file3 didn't inherit OST pool $pool"
7453
7454         local dir4=$MOUNT/$tdir-4
7455         mkdir $dir4 || error "mkdir $dir4 failed"
7456         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7457                 error "$dir4 shouldn't have LOV EA"
7458
7459         # new file created in $dir4 should inherit the pool from
7460         # the filesystem default
7461         local file4=$dir4/$tfile-4
7462         touch $file4 || error "touch $file4 failed"
7463
7464         local file4_pool=$($LFS getstripe -p $file4)
7465         [[ "$file4_pool" = "$pool" ]] ||
7466                 error "$file4 didn't inherit OST pool $pool"
7467
7468         # new subdirectory under non-root directory should inherit
7469         # the default layout from its parent directory
7470         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7471                 error "set directory layout on $dir4 failed"
7472
7473         local dir5=$dir4/$tdir-5
7474         mkdir $dir5 || error "mkdir $dir5 failed"
7475
7476         local dir4_layout=$(get_layout_param $dir4)
7477         local dir5_layout=$(get_layout_param $dir5)
7478         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7479                 error "$dir5 should inherit the default layout from $dir4"
7480 }
7481 run_test 65n "don't inherit default layout from root for new subdirectories"
7482
7483 # bug 2543 - update blocks count on client
7484 test_66() {
7485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7486
7487         COUNT=${COUNT:-8}
7488         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7489         sync; sync_all_data; sync; sync_all_data
7490         cancel_lru_locks osc
7491         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7492         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7493 }
7494 run_test 66 "update inode blocks count on client ==============="
7495
7496 meminfo() {
7497         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7498 }
7499
7500 swap_used() {
7501         swapon -s | awk '($1 == "'$1'") { print $4 }'
7502 }
7503
7504 # bug5265, obdfilter oa2dentry return -ENOENT
7505 # #define OBD_FAIL_SRV_ENOENT 0x217
7506 test_69() {
7507         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7508         remote_ost_nodsh && skip "remote OST with nodsh"
7509
7510         f="$DIR/$tfile"
7511         $LFS setstripe -c 1 -i 0 $f
7512
7513         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7514
7515         do_facet ost1 lctl set_param fail_loc=0x217
7516         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7517         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7518
7519         do_facet ost1 lctl set_param fail_loc=0
7520         $DIRECTIO write $f 0 2 || error "write error"
7521
7522         cancel_lru_locks osc
7523         $DIRECTIO read $f 0 1 || error "read error"
7524
7525         do_facet ost1 lctl set_param fail_loc=0x217
7526         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7527
7528         do_facet ost1 lctl set_param fail_loc=0
7529         rm -f $f
7530 }
7531 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7532
7533 test_71() {
7534         test_mkdir $DIR/$tdir
7535         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7536         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7537 }
7538 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7539
7540 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7542         [ "$RUNAS_ID" = "$UID" ] &&
7543                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7544         # Check that testing environment is properly set up. Skip if not
7545         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7546                 skip_env "User $RUNAS_ID does not exist - skipping"
7547
7548         touch $DIR/$tfile
7549         chmod 777 $DIR/$tfile
7550         chmod ug+s $DIR/$tfile
7551         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7552                 error "$RUNAS dd $DIR/$tfile failed"
7553         # See if we are still setuid/sgid
7554         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7555                 error "S/gid is not dropped on write"
7556         # Now test that MDS is updated too
7557         cancel_lru_locks mdc
7558         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7559                 error "S/gid is not dropped on MDS"
7560         rm -f $DIR/$tfile
7561 }
7562 run_test 72a "Test that remove suid works properly (bug5695) ===="
7563
7564 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7565         local perm
7566
7567         [ "$RUNAS_ID" = "$UID" ] &&
7568                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7569         [ "$RUNAS_ID" -eq 0 ] &&
7570                 skip_env "RUNAS_ID = 0 -- skipping"
7571         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7572         # Check that testing environment is properly set up. Skip if not
7573         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7574                 skip_env "User $RUNAS_ID does not exist - skipping"
7575
7576         touch $DIR/${tfile}-f{g,u}
7577         test_mkdir $DIR/${tfile}-dg
7578         test_mkdir $DIR/${tfile}-du
7579         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7580         chmod g+s $DIR/${tfile}-{f,d}g
7581         chmod u+s $DIR/${tfile}-{f,d}u
7582         for perm in 777 2777 4777; do
7583                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7584                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7585                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7586                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7587         done
7588         true
7589 }
7590 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7591
7592 # bug 3462 - multiple simultaneous MDC requests
7593 test_73() {
7594         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7595
7596         test_mkdir $DIR/d73-1
7597         test_mkdir $DIR/d73-2
7598         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7599         pid1=$!
7600
7601         lctl set_param fail_loc=0x80000129
7602         $MULTIOP $DIR/d73-1/f73-2 Oc &
7603         sleep 1
7604         lctl set_param fail_loc=0
7605
7606         $MULTIOP $DIR/d73-2/f73-3 Oc &
7607         pid3=$!
7608
7609         kill -USR1 $pid1
7610         wait $pid1 || return 1
7611
7612         sleep 25
7613
7614         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7615         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7616         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7617
7618         rm -rf $DIR/d73-*
7619 }
7620 run_test 73 "multiple MDC requests (should not deadlock)"
7621
7622 test_74a() { # bug 6149, 6184
7623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7624
7625         touch $DIR/f74a
7626         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7627         #
7628         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7629         # will spin in a tight reconnection loop
7630         $LCTL set_param fail_loc=0x8000030e
7631         # get any lock that won't be difficult - lookup works.
7632         ls $DIR/f74a
7633         $LCTL set_param fail_loc=0
7634         rm -f $DIR/f74a
7635         true
7636 }
7637 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7638
7639 test_74b() { # bug 13310
7640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7641
7642         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7643         #
7644         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7645         # will spin in a tight reconnection loop
7646         $LCTL set_param fail_loc=0x8000030e
7647         # get a "difficult" lock
7648         touch $DIR/f74b
7649         $LCTL set_param fail_loc=0
7650         rm -f $DIR/f74b
7651         true
7652 }
7653 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7654
7655 test_74c() {
7656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7657
7658         #define OBD_FAIL_LDLM_NEW_LOCK
7659         $LCTL set_param fail_loc=0x319
7660         touch $DIR/$tfile && error "touch successful"
7661         $LCTL set_param fail_loc=0
7662         true
7663 }
7664 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7665
7666 num_inodes() {
7667         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7668 }
7669
7670 test_76() { # Now for bug 20433, added originally in bug 1443
7671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7672
7673         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7674
7675         cancel_lru_locks osc
7676         BEFORE_INODES=$(num_inodes)
7677         echo "before inodes: $BEFORE_INODES"
7678         local COUNT=1000
7679         [ "$SLOW" = "no" ] && COUNT=100
7680         for i in $(seq $COUNT); do
7681                 touch $DIR/$tfile
7682                 rm -f $DIR/$tfile
7683         done
7684         cancel_lru_locks osc
7685         AFTER_INODES=$(num_inodes)
7686         echo "after inodes: $AFTER_INODES"
7687         local wait=0
7688         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7689                 sleep 2
7690                 AFTER_INODES=$(num_inodes)
7691                 wait=$((wait+2))
7692                 echo "wait $wait seconds inodes: $AFTER_INODES"
7693                 if [ $wait -gt 30 ]; then
7694                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7695                 fi
7696         done
7697 }
7698 run_test 76 "confirm clients recycle inodes properly ===="
7699
7700
7701 export ORIG_CSUM=""
7702 set_checksums()
7703 {
7704         # Note: in sptlrpc modes which enable its own bulk checksum, the
7705         # original crc32_le bulk checksum will be automatically disabled,
7706         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7707         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7708         # In this case set_checksums() will not be no-op, because sptlrpc
7709         # bulk checksum will be enabled all through the test.
7710
7711         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7712         lctl set_param -n osc.*.checksums $1
7713         return 0
7714 }
7715
7716 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7717                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7718 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7719                              tr -d [] | head -n1)}
7720 set_checksum_type()
7721 {
7722         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7723         log "set checksum type to $1"
7724         return 0
7725 }
7726 F77_TMP=$TMP/f77-temp
7727 F77SZ=8
7728 setup_f77() {
7729         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7730                 error "error writing to $F77_TMP"
7731 }
7732
7733 test_77a() { # bug 10889
7734         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7735         $GSS && skip_env "could not run with gss"
7736
7737         [ ! -f $F77_TMP ] && setup_f77
7738         set_checksums 1
7739         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7740         set_checksums 0
7741         rm -f $DIR/$tfile
7742 }
7743 run_test 77a "normal checksum read/write operation"
7744
7745 test_77b() { # bug 10889
7746         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7747         $GSS && skip_env "could not run with gss"
7748
7749         [ ! -f $F77_TMP ] && setup_f77
7750         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7751         $LCTL set_param fail_loc=0x80000409
7752         set_checksums 1
7753
7754         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7755                 error "dd error: $?"
7756         $LCTL set_param fail_loc=0
7757
7758         for algo in $CKSUM_TYPES; do
7759                 cancel_lru_locks osc
7760                 set_checksum_type $algo
7761                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7762                 $LCTL set_param fail_loc=0x80000408
7763                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7764                 $LCTL set_param fail_loc=0
7765         done
7766         set_checksums 0
7767         set_checksum_type $ORIG_CSUM_TYPE
7768         rm -f $DIR/$tfile
7769 }
7770 run_test 77b "checksum error on client write, read"
7771
7772 cleanup_77c() {
7773         trap 0
7774         set_checksums 0
7775         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7776         $check_ost &&
7777                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7778         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7779         $check_ost && [ -n "$ost_file_prefix" ] &&
7780                 do_facet ost1 rm -f ${ost_file_prefix}\*
7781 }
7782
7783 test_77c() {
7784         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7785         $GSS && skip_env "could not run with gss"
7786         remote_ost_nodsh && skip "remote OST with nodsh"
7787
7788         local bad1
7789         local osc_file_prefix
7790         local osc_file
7791         local check_ost=false
7792         local ost_file_prefix
7793         local ost_file
7794         local orig_cksum
7795         local dump_cksum
7796         local fid
7797
7798         # ensure corruption will occur on first OSS/OST
7799         $LFS setstripe -i 0 $DIR/$tfile
7800
7801         [ ! -f $F77_TMP ] && setup_f77
7802         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7803                 error "dd write error: $?"
7804         fid=$($LFS path2fid $DIR/$tfile)
7805
7806         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7807         then
7808                 check_ost=true
7809                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7810                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7811         else
7812                 echo "OSS do not support bulk pages dump upon error"
7813         fi
7814
7815         osc_file_prefix=$($LCTL get_param -n debug_path)
7816         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7817
7818         trap cleanup_77c EXIT
7819
7820         set_checksums 1
7821         # enable bulk pages dump upon error on Client
7822         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7823         # enable bulk pages dump upon error on OSS
7824         $check_ost &&
7825                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7826
7827         # flush Client cache to allow next read to reach OSS
7828         cancel_lru_locks osc
7829
7830         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7831         $LCTL set_param fail_loc=0x80000408
7832         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7833         $LCTL set_param fail_loc=0
7834
7835         rm -f $DIR/$tfile
7836
7837         # check cksum dump on Client
7838         osc_file=$(ls ${osc_file_prefix}*)
7839         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7840         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7841         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7842         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7843         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7844                      cksum)
7845         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7846         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7847                 error "dump content does not match on Client"
7848
7849         $check_ost || skip "No need to check cksum dump on OSS"
7850
7851         # check cksum dump on OSS
7852         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7853         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7854         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7855         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7856         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7857                 error "dump content does not match on OSS"
7858
7859         cleanup_77c
7860 }
7861 run_test 77c "checksum error on client read with debug"
7862
7863 test_77d() { # bug 10889
7864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7865         $GSS && skip_env "could not run with gss"
7866
7867         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7868         $LCTL set_param fail_loc=0x80000409
7869         set_checksums 1
7870         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7871                 error "direct write: rc=$?"
7872         $LCTL set_param fail_loc=0
7873         set_checksums 0
7874
7875         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7876         $LCTL set_param fail_loc=0x80000408
7877         set_checksums 1
7878         cancel_lru_locks osc
7879         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7880                 error "direct read: rc=$?"
7881         $LCTL set_param fail_loc=0
7882         set_checksums 0
7883 }
7884 run_test 77d "checksum error on OST direct write, read"
7885
7886 test_77f() { # bug 10889
7887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7888         $GSS && skip_env "could not run with gss"
7889
7890         set_checksums 1
7891         for algo in $CKSUM_TYPES; do
7892                 cancel_lru_locks osc
7893                 set_checksum_type $algo
7894                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7895                 $LCTL set_param fail_loc=0x409
7896                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7897                         error "direct write succeeded"
7898                 $LCTL set_param fail_loc=0
7899         done
7900         set_checksum_type $ORIG_CSUM_TYPE
7901         set_checksums 0
7902 }
7903 run_test 77f "repeat checksum error on write (expect error)"
7904
7905 test_77g() { # bug 10889
7906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7907         $GSS && skip_env "could not run with gss"
7908         remote_ost_nodsh && skip "remote OST with nodsh"
7909
7910         [ ! -f $F77_TMP ] && setup_f77
7911
7912         local file=$DIR/$tfile
7913         stack_trap "rm -f $file" EXIT
7914
7915         $LFS setstripe -c 1 -i 0 $file
7916         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7917         do_facet ost1 lctl set_param fail_loc=0x8000021a
7918         set_checksums 1
7919         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7920                 error "write error: rc=$?"
7921         do_facet ost1 lctl set_param fail_loc=0
7922         set_checksums 0
7923
7924         cancel_lru_locks osc
7925         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7926         do_facet ost1 lctl set_param fail_loc=0x8000021b
7927         set_checksums 1
7928         cmp $F77_TMP $file || error "file compare failed"
7929         do_facet ost1 lctl set_param fail_loc=0
7930         set_checksums 0
7931 }
7932 run_test 77g "checksum error on OST write, read"
7933
7934 test_77k() { # LU-10906
7935         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7936         $GSS && skip_env "could not run with gss"
7937
7938         local cksum_param="osc.$FSNAME*.checksums"
7939         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7940         local checksum
7941         local i
7942
7943         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7944         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7945         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7946                 EXIT
7947
7948         for i in 0 1; do
7949                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7950                         error "failed to set checksum=$i on MGS"
7951                 wait_update $HOSTNAME "$get_checksum" $i
7952                 #remount
7953                 echo "remount client, checksum should be $i"
7954                 remount_client $MOUNT || "failed to remount client"
7955                 checksum=$(eval $get_checksum)
7956                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7957         done
7958         # remove persistent param to avoid races with checksum mountopt below
7959         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7960                 error "failed to delete checksum on MGS"
7961
7962         for opt in "checksum" "nochecksum"; do
7963                 #remount with mount option
7964                 echo "remount client with option $opt, checksum should be $i"
7965                 umount_client $MOUNT || "failed to umount client"
7966                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7967                         "failed to mount client with option '$opt'"
7968                 checksum=$(eval $get_checksum)
7969                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7970                 i=$((i - 1))
7971         done
7972
7973         remount_client $MOUNT || "failed to remount client"
7974 }
7975 run_test 77k "enable/disable checksum correctly"
7976
7977 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
7978 rm -f $F77_TMP
7979 unset F77_TMP
7980
7981 cleanup_test_78() {
7982         trap 0
7983         rm -f $DIR/$tfile
7984 }
7985
7986 test_78() { # bug 10901
7987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7988         remote_ost || skip_env "local OST"
7989
7990         NSEQ=5
7991         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
7992         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
7993         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
7994         echo "MemTotal: $MEMTOTAL"
7995
7996         # reserve 256MB of memory for the kernel and other running processes,
7997         # and then take 1/2 of the remaining memory for the read/write buffers.
7998         if [ $MEMTOTAL -gt 512 ] ;then
7999                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8000         else
8001                 # for those poor memory-starved high-end clusters...
8002                 MEMTOTAL=$((MEMTOTAL / 2))
8003         fi
8004         echo "Mem to use for directio: $MEMTOTAL"
8005
8006         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8007         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8008         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8009         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8010                 head -n1)
8011         echo "Smallest OST: $SMALLESTOST"
8012         [[ $SMALLESTOST -lt 10240 ]] &&
8013                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8014
8015         trap cleanup_test_78 EXIT
8016
8017         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8018                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8019
8020         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8021         echo "File size: $F78SIZE"
8022         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8023         for i in $(seq 1 $NSEQ); do
8024                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8025                 echo directIO rdwr round $i of $NSEQ
8026                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8027         done
8028
8029         cleanup_test_78
8030 }
8031 run_test 78 "handle large O_DIRECT writes correctly ============"
8032
8033 test_79() { # bug 12743
8034         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8035
8036         wait_delete_completed
8037
8038         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8039         BKFREE=$(calc_osc_kbytes kbytesfree)
8040         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8041
8042         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8043         DFTOTAL=`echo $STRING | cut -d, -f1`
8044         DFUSED=`echo $STRING  | cut -d, -f2`
8045         DFAVAIL=`echo $STRING | cut -d, -f3`
8046         DFFREE=$(($DFTOTAL - $DFUSED))
8047
8048         ALLOWANCE=$((64 * $OSTCOUNT))
8049
8050         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8051            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8052                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8053         fi
8054         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8055            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8056                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8057         fi
8058         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8059            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8060                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8061         fi
8062 }
8063 run_test 79 "df report consistency check ======================="
8064
8065 test_80() { # bug 10718
8066         remote_ost_nodsh && skip "remote OST with nodsh"
8067         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8068
8069         # relax strong synchronous semantics for slow backends like ZFS
8070         local soc="obdfilter.*.sync_on_lock_cancel"
8071         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8072         local hosts=
8073         if [ "$soc_old" != "never" ] &&
8074                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8075                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8076                                 facet_active_host $host; done | sort -u)
8077                         do_nodes $hosts lctl set_param $soc=never
8078         fi
8079
8080         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8081         sync; sleep 1; sync
8082         local BEFORE=`date +%s`
8083         cancel_lru_locks osc
8084         local AFTER=`date +%s`
8085         local DIFF=$((AFTER-BEFORE))
8086         if [ $DIFF -gt 1 ] ; then
8087                 error "elapsed for 1M@1T = $DIFF"
8088         fi
8089
8090         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8091
8092         rm -f $DIR/$tfile
8093 }
8094 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8095
8096 test_81a() { # LU-456
8097         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8098         remote_ost_nodsh && skip "remote OST with nodsh"
8099
8100         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8101         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8102         do_facet ost1 lctl set_param fail_loc=0x80000228
8103
8104         # write should trigger a retry and success
8105         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8106         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8107         RC=$?
8108         if [ $RC -ne 0 ] ; then
8109                 error "write should success, but failed for $RC"
8110         fi
8111 }
8112 run_test 81a "OST should retry write when get -ENOSPC ==============="
8113
8114 test_81b() { # LU-456
8115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8116         remote_ost_nodsh && skip "remote OST with nodsh"
8117
8118         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8119         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8120         do_facet ost1 lctl set_param fail_loc=0x228
8121
8122         # write should retry several times and return -ENOSPC finally
8123         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8124         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8125         RC=$?
8126         ENOSPC=28
8127         if [ $RC -ne $ENOSPC ] ; then
8128                 error "dd should fail for -ENOSPC, but succeed."
8129         fi
8130 }
8131 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8132
8133 test_82() { # LU-1031
8134         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8135         local gid1=14091995
8136         local gid2=16022000
8137
8138         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8139         local MULTIPID1=$!
8140         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8141         local MULTIPID2=$!
8142         kill -USR1 $MULTIPID2
8143         sleep 2
8144         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8145                 error "First grouplock does not block second one"
8146         else
8147                 echo "Second grouplock blocks first one"
8148         fi
8149         kill -USR1 $MULTIPID1
8150         wait $MULTIPID1
8151         wait $MULTIPID2
8152 }
8153 run_test 82 "Basic grouplock test"
8154
8155 test_99() {
8156         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8157
8158         test_mkdir $DIR/$tdir.cvsroot
8159         chown $RUNAS_ID $DIR/$tdir.cvsroot
8160
8161         cd $TMP
8162         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8163
8164         cd /etc/init.d
8165         # some versions of cvs import exit(1) when asked to import links or
8166         # files they can't read.  ignore those files.
8167         local toignore=$(find . -type l -printf '-I %f\n' -o \
8168                          ! -perm /4 -printf '-I %f\n')
8169         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8170                 $tdir.reposname vtag rtag
8171
8172         cd $DIR
8173         test_mkdir $DIR/$tdir.reposname
8174         chown $RUNAS_ID $DIR/$tdir.reposname
8175         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8176
8177         cd $DIR/$tdir.reposname
8178         $RUNAS touch foo99
8179         $RUNAS cvs add -m 'addmsg' foo99
8180         $RUNAS cvs update
8181         $RUNAS cvs commit -m 'nomsg' foo99
8182         rm -fr $DIR/$tdir.cvsroot
8183 }
8184 run_test 99 "cvs strange file/directory operations"
8185
8186 test_100() {
8187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8188         [[ "$NETTYPE" =~ tcp ]] ||
8189                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8190         remote_ost_nodsh && skip "remote OST with nodsh"
8191         remote_mds_nodsh && skip "remote MDS with nodsh"
8192         remote_servers ||
8193                 skip "useless for local single node setup"
8194
8195         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8196                 [ "$PROT" != "tcp" ] && continue
8197                 RPORT=$(echo $REMOTE | cut -d: -f2)
8198                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8199
8200                 rc=0
8201                 LPORT=`echo $LOCAL | cut -d: -f2`
8202                 if [ $LPORT -ge 1024 ]; then
8203                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8204                         netstat -tna
8205                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8206                 fi
8207         done
8208         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8209 }
8210 run_test 100 "check local port using privileged port ==========="
8211
8212 function get_named_value()
8213 {
8214     local tag
8215
8216     tag=$1
8217     while read ;do
8218         line=$REPLY
8219         case $line in
8220         $tag*)
8221             echo $line | sed "s/^$tag[ ]*//"
8222             break
8223             ;;
8224         esac
8225     done
8226 }
8227
8228 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8229                    awk '/^max_cached_mb/ { print $2 }')
8230
8231 cleanup_101a() {
8232         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8233         trap 0
8234 }
8235
8236 test_101a() {
8237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8238         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8239
8240         local s
8241         local discard
8242         local nreads=10000
8243         local cache_limit=32
8244
8245         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8246         trap cleanup_101a EXIT
8247         $LCTL set_param -n llite.*.read_ahead_stats 0
8248         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8249
8250         #
8251         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8252         #
8253         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8254         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8255
8256         discard=0
8257         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8258                 get_named_value 'read but discarded' | cut -d" " -f1); do
8259                         discard=$(($discard + $s))
8260         done
8261         cleanup_101a
8262
8263         if [[ $(($discard * 10)) -gt $nreads ]]; then
8264                 $LCTL get_param osc.*-osc*.rpc_stats
8265                 $LCTL get_param llite.*.read_ahead_stats
8266                 error "too many ($discard) discarded pages"
8267         fi
8268         rm -f $DIR/$tfile || true
8269 }
8270 run_test 101a "check read-ahead for random reads"
8271
8272 setup_test101bc() {
8273         test_mkdir $DIR/$tdir
8274         local ssize=$1
8275         local FILE_LENGTH=$2
8276         STRIPE_OFFSET=0
8277
8278         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8279
8280         local list=$(comma_list $(osts_nodes))
8281         set_osd_param $list '' read_cache_enable 0
8282         set_osd_param $list '' writethrough_cache_enable 0
8283
8284         trap cleanup_test101bc EXIT
8285         # prepare the read-ahead file
8286         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8287
8288         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8289                                 count=$FILE_SIZE_MB 2> /dev/null
8290
8291 }
8292
8293 cleanup_test101bc() {
8294         trap 0
8295         rm -rf $DIR/$tdir
8296         rm -f $DIR/$tfile
8297
8298         local list=$(comma_list $(osts_nodes))
8299         set_osd_param $list '' read_cache_enable 1
8300         set_osd_param $list '' writethrough_cache_enable 1
8301 }
8302
8303 calc_total() {
8304         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8305 }
8306
8307 ra_check_101() {
8308         local READ_SIZE=$1
8309         local STRIPE_SIZE=$2
8310         local FILE_LENGTH=$3
8311         local RA_INC=1048576
8312         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8313         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8314                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8315         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8316                         get_named_value 'read but discarded' |
8317                         cut -d" " -f1 | calc_total)
8318         if [[ $DISCARD -gt $discard_limit ]]; then
8319                 $LCTL get_param llite.*.read_ahead_stats
8320                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8321         else
8322                 echo "Read-ahead success for size ${READ_SIZE}"
8323         fi
8324 }
8325
8326 test_101b() {
8327         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8328         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8329
8330         local STRIPE_SIZE=1048576
8331         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8332
8333         if [ $SLOW == "yes" ]; then
8334                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8335         else
8336                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8337         fi
8338
8339         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8340
8341         # prepare the read-ahead file
8342         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8343         cancel_lru_locks osc
8344         for BIDX in 2 4 8 16 32 64 128 256
8345         do
8346                 local BSIZE=$((BIDX*4096))
8347                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8348                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8349                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8350                 $LCTL set_param -n llite.*.read_ahead_stats 0
8351                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8352                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8353                 cancel_lru_locks osc
8354                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8355         done
8356         cleanup_test101bc
8357         true
8358 }
8359 run_test 101b "check stride-io mode read-ahead ================="
8360
8361 test_101c() {
8362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8363
8364         local STRIPE_SIZE=1048576
8365         local FILE_LENGTH=$((STRIPE_SIZE*100))
8366         local nreads=10000
8367         local rsize=65536
8368         local osc_rpc_stats
8369
8370         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8371
8372         cancel_lru_locks osc
8373         $LCTL set_param osc.*.rpc_stats 0
8374         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8375         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8376                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8377                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8378                 local size
8379
8380                 if [ $lines -le 20 ]; then
8381                         continue
8382                 fi
8383                 for size in 1 2 4 8; do
8384                         local rpc=$(echo "$stats" |
8385                                     awk '($1 == "'$size':") {print $2; exit; }')
8386                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8387                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8388                 done
8389                 echo "$osc_rpc_stats check passed!"
8390         done
8391         cleanup_test101bc
8392         true
8393 }
8394 run_test 101c "check stripe_size aligned read-ahead ================="
8395
8396 set_read_ahead() {
8397         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8398         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8399 }
8400
8401 test_101d() {
8402         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8403
8404         local file=$DIR/$tfile
8405         local sz_MB=${FILESIZE_101d:-500}
8406         local ra_MB=${READAHEAD_MB:-40}
8407
8408         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8409         [ $free_MB -lt $sz_MB ] &&
8410                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8411
8412         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8413         $LFS setstripe -c -1 $file || error "setstripe failed"
8414
8415         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8416         echo Cancel LRU locks on lustre client to flush the client cache
8417         cancel_lru_locks osc
8418
8419         echo Disable read-ahead
8420         local old_READAHEAD=$(set_read_ahead 0)
8421
8422         echo Reading the test file $file with read-ahead disabled
8423         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8424
8425         echo Cancel LRU locks on lustre client to flush the client cache
8426         cancel_lru_locks osc
8427         echo Enable read-ahead with ${ra_MB}MB
8428         set_read_ahead $ra_MB
8429
8430         echo Reading the test file $file with read-ahead enabled
8431         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8432
8433         echo "read-ahead disabled time read $raOFF"
8434         echo "read-ahead enabled  time read $raON"
8435
8436         set_read_ahead $old_READAHEAD
8437         rm -f $file
8438         wait_delete_completed
8439
8440         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8441                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8442 }
8443 run_test 101d "file read with and without read-ahead enabled"
8444
8445 test_101e() {
8446         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8447
8448         local file=$DIR/$tfile
8449         local size_KB=500  #KB
8450         local count=100
8451         local bsize=1024
8452
8453         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8454         local need_KB=$((count * size_KB))
8455         [[ $free_KB -le $need_KB ]] &&
8456                 skip_env "Need free space $need_KB, have $free_KB"
8457
8458         echo "Creating $count ${size_KB}K test files"
8459         for ((i = 0; i < $count; i++)); do
8460                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8461         done
8462
8463         echo "Cancel LRU locks on lustre client to flush the client cache"
8464         cancel_lru_locks $OSC
8465
8466         echo "Reset readahead stats"
8467         $LCTL set_param -n llite.*.read_ahead_stats 0
8468
8469         for ((i = 0; i < $count; i++)); do
8470                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8471         done
8472
8473         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8474                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8475
8476         for ((i = 0; i < $count; i++)); do
8477                 rm -rf $file.$i 2>/dev/null
8478         done
8479
8480         #10000 means 20% reads are missing in readahead
8481         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8482 }
8483 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8484
8485 test_101f() {
8486         which iozone || skip_env "no iozone installed"
8487
8488         local old_debug=$($LCTL get_param debug)
8489         old_debug=${old_debug#*=}
8490         $LCTL set_param debug="reada mmap"
8491
8492         # create a test file
8493         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8494
8495         echo Cancel LRU locks on lustre client to flush the client cache
8496         cancel_lru_locks osc
8497
8498         echo Reset readahead stats
8499         $LCTL set_param -n llite.*.read_ahead_stats 0
8500
8501         echo mmap read the file with small block size
8502         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8503                 > /dev/null 2>&1
8504
8505         echo checking missing pages
8506         $LCTL get_param llite.*.read_ahead_stats
8507         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8508                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8509
8510         $LCTL set_param debug="$old_debug"
8511         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8512         rm -f $DIR/$tfile
8513 }
8514 run_test 101f "check mmap read performance"
8515
8516 test_101g_brw_size_test() {
8517         local mb=$1
8518         local pages=$((mb * 1048576 / PAGE_SIZE))
8519         local file=$DIR/$tfile
8520
8521         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8522                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8523         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8524                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8525                         return 2
8526         done
8527
8528         stack_trap "rm -f $file" EXIT
8529         $LCTL set_param -n osc.*.rpc_stats=0
8530
8531         # 10 RPCs should be enough for the test
8532         local count=10
8533         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8534                 { error "dd write ${mb} MB blocks failed"; return 3; }
8535         cancel_lru_locks osc
8536         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8537                 { error "dd write ${mb} MB blocks failed"; return 4; }
8538
8539         # calculate number of full-sized read and write RPCs
8540         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8541                 sed -n '/pages per rpc/,/^$/p' |
8542                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8543                 END { print reads,writes }'))
8544         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8545                 return 5
8546         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8547                 return 6
8548
8549         return 0
8550 }
8551
8552 test_101g() {
8553         remote_ost_nodsh && skip "remote OST with nodsh"
8554
8555         local rpcs
8556         local osts=$(get_facets OST)
8557         local list=$(comma_list $(osts_nodes))
8558         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8559         local brw_size="obdfilter.*.brw_size"
8560
8561         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8562
8563         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8564
8565         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8566                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8567                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8568            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8569                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8570                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8571
8572                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8573                         suffix="M"
8574
8575                 if [[ $orig_mb -lt 16 ]]; then
8576                         save_lustre_params $osts "$brw_size" > $p
8577                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8578                                 error "set 16MB RPC size failed"
8579
8580                         echo "remount client to enable new RPC size"
8581                         remount_client $MOUNT || error "remount_client failed"
8582                 fi
8583
8584                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8585                 # should be able to set brw_size=12, but no rpc_stats for that
8586                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8587         fi
8588
8589         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8590
8591         if [[ $orig_mb -lt 16 ]]; then
8592                 restore_lustre_params < $p
8593                 remount_client $MOUNT || error "remount_client restore failed"
8594         fi
8595
8596         rm -f $p $DIR/$tfile
8597 }
8598 run_test 101g "Big bulk(4/16 MiB) readahead"
8599
8600 setup_test102() {
8601         test_mkdir $DIR/$tdir
8602         chown $RUNAS_ID $DIR/$tdir
8603         STRIPE_SIZE=65536
8604         STRIPE_OFFSET=1
8605         STRIPE_COUNT=$OSTCOUNT
8606         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8607
8608         trap cleanup_test102 EXIT
8609         cd $DIR
8610         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8611         cd $DIR/$tdir
8612         for num in 1 2 3 4; do
8613                 for count in $(seq 1 $STRIPE_COUNT); do
8614                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8615                                 local size=`expr $STRIPE_SIZE \* $num`
8616                                 local file=file"$num-$idx-$count"
8617                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8618                         done
8619                 done
8620         done
8621
8622         cd $DIR
8623         $1 tar cf $TMP/f102.tar $tdir --xattrs
8624 }
8625
8626 cleanup_test102() {
8627         trap 0
8628         rm -f $TMP/f102.tar
8629         rm -rf $DIR/d0.sanity/d102
8630 }
8631
8632 test_102a() {
8633         [ "$UID" != 0 ] && skip "must run as root"
8634         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8635                 skip_env "must have user_xattr"
8636
8637         [ -z "$(which setfattr 2>/dev/null)" ] &&
8638                 skip_env "could not find setfattr"
8639
8640         local testfile=$DIR/$tfile
8641
8642         touch $testfile
8643         echo "set/get xattr..."
8644         setfattr -n trusted.name1 -v value1 $testfile ||
8645                 error "setfattr -n trusted.name1=value1 $testfile failed"
8646         getfattr -n trusted.name1 $testfile 2> /dev/null |
8647           grep "trusted.name1=.value1" ||
8648                 error "$testfile missing trusted.name1=value1"
8649
8650         setfattr -n user.author1 -v author1 $testfile ||
8651                 error "setfattr -n user.author1=author1 $testfile failed"
8652         getfattr -n user.author1 $testfile 2> /dev/null |
8653           grep "user.author1=.author1" ||
8654                 error "$testfile missing trusted.author1=author1"
8655
8656         echo "listxattr..."
8657         setfattr -n trusted.name2 -v value2 $testfile ||
8658                 error "$testfile unable to set trusted.name2"
8659         setfattr -n trusted.name3 -v value3 $testfile ||
8660                 error "$testfile unable to set trusted.name3"
8661         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8662             grep "trusted.name" | wc -l) -eq 3 ] ||
8663                 error "$testfile missing 3 trusted.name xattrs"
8664
8665         setfattr -n user.author2 -v author2 $testfile ||
8666                 error "$testfile unable to set user.author2"
8667         setfattr -n user.author3 -v author3 $testfile ||
8668                 error "$testfile unable to set user.author3"
8669         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8670             grep "user.author" | wc -l) -eq 3 ] ||
8671                 error "$testfile missing 3 user.author xattrs"
8672
8673         echo "remove xattr..."
8674         setfattr -x trusted.name1 $testfile ||
8675                 error "$testfile error deleting trusted.name1"
8676         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8677                 error "$testfile did not delete trusted.name1 xattr"
8678
8679         setfattr -x user.author1 $testfile ||
8680                 error "$testfile error deleting user.author1"
8681         echo "set lustre special xattr ..."
8682         $LFS setstripe -c1 $testfile
8683         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8684                 awk -F "=" '/trusted.lov/ { print $2 }' )
8685         setfattr -n "trusted.lov" -v $lovea $testfile ||
8686                 error "$testfile doesn't ignore setting trusted.lov again"
8687         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8688                 error "$testfile allow setting invalid trusted.lov"
8689         rm -f $testfile
8690 }
8691 run_test 102a "user xattr test =================================="
8692
8693 test_102b() {
8694         [ -z "$(which setfattr 2>/dev/null)" ] &&
8695                 skip_env "could not find setfattr"
8696         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8697
8698         # b10930: get/set/list trusted.lov xattr
8699         echo "get/set/list trusted.lov xattr ..."
8700         local testfile=$DIR/$tfile
8701         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8702                 error "setstripe failed"
8703         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8704                 error "getstripe failed"
8705         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8706                 error "can't get trusted.lov from $testfile"
8707
8708         local testfile2=${testfile}2
8709         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8710                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8711
8712         $MCREATE $testfile2
8713         setfattr -n trusted.lov -v $value $testfile2
8714         local stripe_size=$($LFS getstripe -S $testfile2)
8715         local stripe_count=$($LFS getstripe -c $testfile2)
8716         [[ $stripe_size -eq 65536 ]] ||
8717                 error "stripe size $stripe_size != 65536"
8718         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8719                 error "stripe count $stripe_count != $STRIPECOUNT"
8720         rm -f $DIR/$tfile
8721 }
8722 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8723
8724 test_102c() {
8725         [ -z "$(which setfattr 2>/dev/null)" ] &&
8726                 skip_env "could not find setfattr"
8727         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8728
8729         # b10930: get/set/list lustre.lov xattr
8730         echo "get/set/list lustre.lov xattr ..."
8731         test_mkdir $DIR/$tdir
8732         chown $RUNAS_ID $DIR/$tdir
8733         local testfile=$DIR/$tdir/$tfile
8734         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8735                 error "setstripe failed"
8736         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8737                 error "getstripe failed"
8738         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8739         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8740
8741         local testfile2=${testfile}2
8742         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8743                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8744
8745         $RUNAS $MCREATE $testfile2
8746         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8747         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8748         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8749         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8750         [ $stripe_count -eq $STRIPECOUNT ] ||
8751                 error "stripe count $stripe_count != $STRIPECOUNT"
8752 }
8753 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8754
8755 compare_stripe_info1() {
8756         local stripe_index_all_zero=true
8757
8758         for num in 1 2 3 4; do
8759                 for count in $(seq 1 $STRIPE_COUNT); do
8760                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8761                                 local size=$((STRIPE_SIZE * num))
8762                                 local file=file"$num-$offset-$count"
8763                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8764                                 [[ $stripe_size -ne $size ]] &&
8765                                     error "$file: size $stripe_size != $size"
8766                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8767                                 # allow fewer stripes to be created, ORI-601
8768                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8769                                     error "$file: count $stripe_count != $count"
8770                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8771                                 [[ $stripe_index -ne 0 ]] &&
8772                                         stripe_index_all_zero=false
8773                         done
8774                 done
8775         done
8776         $stripe_index_all_zero &&
8777                 error "all files are being extracted starting from OST index 0"
8778         return 0
8779 }
8780
8781 have_xattrs_include() {
8782         tar --help | grep -q xattrs-include &&
8783                 echo --xattrs-include="lustre.*"
8784 }
8785
8786 test_102d() {
8787         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8788         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8789
8790         XINC=$(have_xattrs_include)
8791         setup_test102
8792         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8793         cd $DIR/$tdir/$tdir
8794         compare_stripe_info1
8795 }
8796 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8797
8798 test_102f() {
8799         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8801
8802         XINC=$(have_xattrs_include)
8803         setup_test102
8804         test_mkdir $DIR/$tdir.restore
8805         cd $DIR
8806         tar cf - --xattrs $tdir | tar xf - \
8807                 -C $DIR/$tdir.restore --xattrs $XINC
8808         cd $DIR/$tdir.restore/$tdir
8809         compare_stripe_info1
8810 }
8811 run_test 102f "tar copy files, not keep osts"
8812
8813 grow_xattr() {
8814         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8815                 skip "must have user_xattr"
8816         [ -z "$(which setfattr 2>/dev/null)" ] &&
8817                 skip_env "could not find setfattr"
8818         [ -z "$(which getfattr 2>/dev/null)" ] &&
8819                 skip_env "could not find getfattr"
8820
8821         local xsize=${1:-1024}  # in bytes
8822         local file=$DIR/$tfile
8823         local value="$(generate_string $xsize)"
8824         local xbig=trusted.big
8825         local toobig=$2
8826
8827         touch $file
8828         log "save $xbig on $file"
8829         if [ -z "$toobig" ]
8830         then
8831                 setfattr -n $xbig -v $value $file ||
8832                         error "saving $xbig on $file failed"
8833         else
8834                 setfattr -n $xbig -v $value $file &&
8835                         error "saving $xbig on $file succeeded"
8836                 return 0
8837         fi
8838
8839         local orig=$(get_xattr_value $xbig $file)
8840         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8841
8842         local xsml=trusted.sml
8843         log "save $xsml on $file"
8844         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8845
8846         local new=$(get_xattr_value $xbig $file)
8847         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8848
8849         log "grow $xsml on $file"
8850         setfattr -n $xsml -v "$value" $file ||
8851                 error "growing $xsml on $file failed"
8852
8853         new=$(get_xattr_value $xbig $file)
8854         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8855         log "$xbig still valid after growing $xsml"
8856
8857         rm -f $file
8858 }
8859
8860 test_102h() { # bug 15777
8861         grow_xattr 1024
8862 }
8863 run_test 102h "grow xattr from inside inode to external block"
8864
8865 test_102ha() {
8866         large_xattr_enabled || skip_env "ea_inode feature disabled"
8867
8868         echo "setting xattr of max xattr size: $(max_xattr_size)"
8869         grow_xattr $(max_xattr_size)
8870
8871         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8872         echo "This should fail:"
8873         grow_xattr $(($(max_xattr_size) + 10)) 1
8874 }
8875 run_test 102ha "grow xattr from inside inode to external inode"
8876
8877 test_102i() { # bug 17038
8878         [ -z "$(which getfattr 2>/dev/null)" ] &&
8879                 skip "could not find getfattr"
8880
8881         touch $DIR/$tfile
8882         ln -s $DIR/$tfile $DIR/${tfile}link
8883         getfattr -n trusted.lov $DIR/$tfile ||
8884                 error "lgetxattr on $DIR/$tfile failed"
8885         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8886                 grep -i "no such attr" ||
8887                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8888         rm -f $DIR/$tfile $DIR/${tfile}link
8889 }
8890 run_test 102i "lgetxattr test on symbolic link ============"
8891
8892 test_102j() {
8893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8894         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8895
8896         XINC=$(have_xattrs_include)
8897         setup_test102 "$RUNAS"
8898         chown $RUNAS_ID $DIR/$tdir
8899         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8900         cd $DIR/$tdir/$tdir
8901         compare_stripe_info1 "$RUNAS"
8902 }
8903 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8904
8905 test_102k() {
8906         [ -z "$(which setfattr 2>/dev/null)" ] &&
8907                 skip "could not find setfattr"
8908
8909         touch $DIR/$tfile
8910         # b22187 just check that does not crash for regular file.
8911         setfattr -n trusted.lov $DIR/$tfile
8912         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8913         local test_kdir=$DIR/$tdir
8914         test_mkdir $test_kdir
8915         local default_size=$($LFS getstripe -S $test_kdir)
8916         local default_count=$($LFS getstripe -c $test_kdir)
8917         local default_offset=$($LFS getstripe -i $test_kdir)
8918         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8919                 error 'dir setstripe failed'
8920         setfattr -n trusted.lov $test_kdir
8921         local stripe_size=$($LFS getstripe -S $test_kdir)
8922         local stripe_count=$($LFS getstripe -c $test_kdir)
8923         local stripe_offset=$($LFS getstripe -i $test_kdir)
8924         [ $stripe_size -eq $default_size ] ||
8925                 error "stripe size $stripe_size != $default_size"
8926         [ $stripe_count -eq $default_count ] ||
8927                 error "stripe count $stripe_count != $default_count"
8928         [ $stripe_offset -eq $default_offset ] ||
8929                 error "stripe offset $stripe_offset != $default_offset"
8930         rm -rf $DIR/$tfile $test_kdir
8931 }
8932 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8933
8934 test_102l() {
8935         [ -z "$(which getfattr 2>/dev/null)" ] &&
8936                 skip "could not find getfattr"
8937
8938         # LU-532 trusted. xattr is invisible to non-root
8939         local testfile=$DIR/$tfile
8940
8941         touch $testfile
8942
8943         echo "listxattr as user..."
8944         chown $RUNAS_ID $testfile
8945         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8946             grep -q "trusted" &&
8947                 error "$testfile trusted xattrs are user visible"
8948
8949         return 0;
8950 }
8951 run_test 102l "listxattr size test =================================="
8952
8953 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
8954         local path=$DIR/$tfile
8955         touch $path
8956
8957         listxattr_size_check $path || error "listattr_size_check $path failed"
8958 }
8959 run_test 102m "Ensure listxattr fails on small bufffer ========"
8960
8961 cleanup_test102
8962
8963 getxattr() { # getxattr path name
8964         # Return the base64 encoding of the value of xattr name on path.
8965         local path=$1
8966         local name=$2
8967
8968         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
8969         # file: $path
8970         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8971         #
8972         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
8973
8974         getfattr --absolute-names --encoding=base64 --name=$name $path |
8975                 awk -F= -v name=$name '$1 == name {
8976                         print substr($0, index($0, "=") + 1);
8977         }'
8978 }
8979
8980 test_102n() { # LU-4101 mdt: protect internal xattrs
8981         [ -z "$(which setfattr 2>/dev/null)" ] &&
8982                 skip "could not find setfattr"
8983         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
8984         then
8985                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
8986         fi
8987
8988         local file0=$DIR/$tfile.0
8989         local file1=$DIR/$tfile.1
8990         local xattr0=$TMP/$tfile.0
8991         local xattr1=$TMP/$tfile.1
8992         local namelist="lov lma lmv link fid version som hsm"
8993         local name
8994         local value
8995
8996         rm -rf $file0 $file1 $xattr0 $xattr1
8997         touch $file0 $file1
8998
8999         # Get 'before' xattrs of $file1.
9000         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9001
9002         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9003                 namelist+=" lfsck_namespace"
9004         for name in $namelist; do
9005                 # Try to copy xattr from $file0 to $file1.
9006                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9007
9008                 setfattr --name=trusted.$name --value="$value" $file1 ||
9009                         error "setxattr 'trusted.$name' failed"
9010
9011                 # Try to set a garbage xattr.
9012                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9013
9014                 if [[ x$name == "xlov" ]]; then
9015                         setfattr --name=trusted.lov --value="$value" $file1 &&
9016                         error "setxattr invalid 'trusted.lov' success"
9017                 else
9018                         setfattr --name=trusted.$name --value="$value" $file1 ||
9019                                 error "setxattr invalid 'trusted.$name' failed"
9020                 fi
9021
9022                 # Try to remove the xattr from $file1. We don't care if this
9023                 # appears to succeed or fail, we just don't want there to be
9024                 # any changes or crashes.
9025                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9026         done
9027
9028         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9029         then
9030                 name="lfsck_ns"
9031                 # Try to copy xattr from $file0 to $file1.
9032                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9033
9034                 setfattr --name=trusted.$name --value="$value" $file1 ||
9035                         error "setxattr 'trusted.$name' failed"
9036
9037                 # Try to set a garbage xattr.
9038                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9039
9040                 setfattr --name=trusted.$name --value="$value" $file1 ||
9041                         error "setxattr 'trusted.$name' failed"
9042
9043                 # Try to remove the xattr from $file1. We don't care if this
9044                 # appears to succeed or fail, we just don't want there to be
9045                 # any changes or crashes.
9046                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9047         fi
9048
9049         # Get 'after' xattrs of file1.
9050         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9051
9052         if ! diff $xattr0 $xattr1; then
9053                 error "before and after xattrs of '$file1' differ"
9054         fi
9055
9056         rm -rf $file0 $file1 $xattr0 $xattr1
9057
9058         return 0
9059 }
9060 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9061
9062 test_102p() { # LU-4703 setxattr did not check ownership
9063         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9064                 skip "MDS needs to be at least 2.5.56"
9065
9066         local testfile=$DIR/$tfile
9067
9068         touch $testfile
9069
9070         echo "setfacl as user..."
9071         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9072         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9073
9074         echo "setfattr as user..."
9075         setfacl -m "u:$RUNAS_ID:---" $testfile
9076         $RUNAS setfattr -x system.posix_acl_access $testfile
9077         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9078 }
9079 run_test 102p "check setxattr(2) correctly fails without permission"
9080
9081 test_102q() {
9082         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9083                 skip "MDS needs to be at least 2.6.92"
9084
9085         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9086 }
9087 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9088
9089 test_102r() {
9090         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9091                 skip "MDS needs to be at least 2.6.93"
9092
9093         touch $DIR/$tfile || error "touch"
9094         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9095         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9096         rm $DIR/$tfile || error "rm"
9097
9098         #normal directory
9099         mkdir -p $DIR/$tdir || error "mkdir"
9100         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9101         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9102         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9103                 error "$testfile error deleting user.author1"
9104         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9105                 grep "user.$(basename $tdir)" &&
9106                 error "$tdir did not delete user.$(basename $tdir)"
9107         rmdir $DIR/$tdir || error "rmdir"
9108
9109         #striped directory
9110         test_mkdir $DIR/$tdir
9111         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9112         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9113         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9114                 error "$testfile error deleting user.author1"
9115         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9116                 grep "user.$(basename $tdir)" &&
9117                 error "$tdir did not delete user.$(basename $tdir)"
9118         rmdir $DIR/$tdir || error "rm striped dir"
9119 }
9120 run_test 102r "set EAs with empty values"
9121
9122 test_102s() {
9123         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9124                 skip "MDS needs to be at least 2.11.52"
9125
9126         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9127
9128         save_lustre_params client "llite.*.xattr_cache" > $save
9129
9130         for cache in 0 1; do
9131                 lctl set_param llite.*.xattr_cache=$cache
9132
9133                 rm -f $DIR/$tfile
9134                 touch $DIR/$tfile || error "touch"
9135                 for prefix in lustre security system trusted user; do
9136                         # Note getxattr() may fail with 'Operation not
9137                         # supported' or 'No such attribute' depending
9138                         # on prefix and cache.
9139                         getfattr -n $prefix.n102s $DIR/$tfile &&
9140                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9141                 done
9142         done
9143
9144         restore_lustre_params < $save
9145 }
9146 run_test 102s "getting nonexistent xattrs should fail"
9147
9148 test_102t() {
9149         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9150                 skip "MDS needs to be at least 2.11.52"
9151
9152         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9153
9154         save_lustre_params client "llite.*.xattr_cache" > $save
9155
9156         for cache in 0 1; do
9157                 lctl set_param llite.*.xattr_cache=$cache
9158
9159                 for buf_size in 0 256; do
9160                         rm -f $DIR/$tfile
9161                         touch $DIR/$tfile || error "touch"
9162                         setfattr -n user.multiop $DIR/$tfile
9163                         $MULTIOP $DIR/$tfile oa$buf_size ||
9164                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9165                 done
9166         done
9167
9168         restore_lustre_params < $save
9169 }
9170 run_test 102t "zero length xattr values handled correctly"
9171
9172 run_acl_subtest()
9173 {
9174     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9175     return $?
9176 }
9177
9178 test_103a() {
9179         [ "$UID" != 0 ] && skip "must run as root"
9180         $GSS && skip_env "could not run under gss"
9181         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9182                 skip_env "must have acl enabled"
9183         [ -z "$(which setfacl 2>/dev/null)" ] &&
9184                 skip_env "could not find setfacl"
9185         remote_mds_nodsh && skip "remote MDS with nodsh"
9186
9187         gpasswd -a daemon bin                           # LU-5641
9188         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9189
9190         declare -a identity_old
9191
9192         for num in $(seq $MDSCOUNT); do
9193                 switch_identity $num true || identity_old[$num]=$?
9194         done
9195
9196         SAVE_UMASK=$(umask)
9197         umask 0022
9198         mkdir -p $DIR/$tdir
9199         cd $DIR/$tdir
9200
9201         echo "performing cp ..."
9202         run_acl_subtest cp || error "run_acl_subtest cp failed"
9203         echo "performing getfacl-noacl..."
9204         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9205         echo "performing misc..."
9206         run_acl_subtest misc || error  "misc test failed"
9207         echo "performing permissions..."
9208         run_acl_subtest permissions || error "permissions failed"
9209         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9210         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9211                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9212                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9213         then
9214                 echo "performing permissions xattr..."
9215                 run_acl_subtest permissions_xattr ||
9216                         error "permissions_xattr failed"
9217         fi
9218         echo "performing setfacl..."
9219         run_acl_subtest setfacl || error  "setfacl test failed"
9220
9221         # inheritance test got from HP
9222         echo "performing inheritance..."
9223         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9224         chmod +x make-tree || error "chmod +x failed"
9225         run_acl_subtest inheritance || error "inheritance test failed"
9226         rm -f make-tree
9227
9228         echo "LU-974 ignore umask when acl is enabled..."
9229         run_acl_subtest 974 || error "LU-974 umask test failed"
9230         if [ $MDSCOUNT -ge 2 ]; then
9231                 run_acl_subtest 974_remote ||
9232                         error "LU-974 umask test failed under remote dir"
9233         fi
9234
9235         echo "LU-2561 newly created file is same size as directory..."
9236         if [ "$mds1_FSTYPE" != "zfs" ]; then
9237                 run_acl_subtest 2561 || error "LU-2561 test failed"
9238         else
9239                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9240         fi
9241
9242         run_acl_subtest 4924 || error "LU-4924 test failed"
9243
9244         cd $SAVE_PWD
9245         umask $SAVE_UMASK
9246
9247         for num in $(seq $MDSCOUNT); do
9248                 if [ "${identity_old[$num]}" = 1 ]; then
9249                         switch_identity $num false || identity_old[$num]=$?
9250                 fi
9251         done
9252 }
9253 run_test 103a "acl test"
9254
9255 test_103b() {
9256         declare -a pids
9257         local U
9258
9259         for U in {0..511}; do
9260                 {
9261                 local O=$(printf "%04o" $U)
9262
9263                 umask $(printf "%04o" $((511 ^ $O)))
9264                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9265                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9266
9267                 (( $S == ($O & 0666) )) ||
9268                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9269
9270                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9271                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9272                 (( $S == ($O & 0666) )) ||
9273                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9274
9275                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9276                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9277                 (( $S == ($O & 0666) )) ||
9278                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9279                 rm -f $DIR/$tfile.[smp]$0
9280                 } &
9281                 local pid=$!
9282
9283                 # limit the concurrently running threads to 64. LU-11878
9284                 local idx=$((U % 64))
9285                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9286                 pids[idx]=$pid
9287         done
9288         wait
9289 }
9290 run_test 103b "umask lfs setstripe"
9291
9292 test_103c() {
9293         mkdir -p $DIR/$tdir
9294         cp -rp $DIR/$tdir $DIR/$tdir.bak
9295
9296         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9297                 error "$DIR/$tdir shouldn't contain default ACL"
9298         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9299                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9300         true
9301 }
9302 run_test 103c "'cp -rp' won't set empty acl"
9303
9304 test_104a() {
9305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9306
9307         touch $DIR/$tfile
9308         lfs df || error "lfs df failed"
9309         lfs df -ih || error "lfs df -ih failed"
9310         lfs df -h $DIR || error "lfs df -h $DIR failed"
9311         lfs df -i $DIR || error "lfs df -i $DIR failed"
9312         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9313         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9314
9315         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9316         lctl --device %$OSC deactivate
9317         lfs df || error "lfs df with deactivated OSC failed"
9318         lctl --device %$OSC activate
9319         # wait the osc back to normal
9320         wait_osc_import_ready client ost
9321
9322         lfs df || error "lfs df with reactivated OSC failed"
9323         rm -f $DIR/$tfile
9324 }
9325 run_test 104a "lfs df [-ih] [path] test ========================="
9326
9327 test_104b() {
9328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9329         [ $RUNAS_ID -eq $UID ] &&
9330                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9331
9332         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9333                         grep "Permission denied" | wc -l)))
9334         if [ $denied_cnt -ne 0 ]; then
9335                 error "lfs check servers test failed"
9336         fi
9337 }
9338 run_test 104b "$RUNAS lfs check servers test ===================="
9339
9340 test_105a() {
9341         # doesn't work on 2.4 kernels
9342         touch $DIR/$tfile
9343         if $(flock_is_enabled); then
9344                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9345         else
9346                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9347         fi
9348         rm -f $DIR/$tfile
9349 }
9350 run_test 105a "flock when mounted without -o flock test ========"
9351
9352 test_105b() {
9353         touch $DIR/$tfile
9354         if $(flock_is_enabled); then
9355                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9356         else
9357                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9358         fi
9359         rm -f $DIR/$tfile
9360 }
9361 run_test 105b "fcntl when mounted without -o flock test ========"
9362
9363 test_105c() {
9364         touch $DIR/$tfile
9365         if $(flock_is_enabled); then
9366                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9367         else
9368                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9369         fi
9370         rm -f $DIR/$tfile
9371 }
9372 run_test 105c "lockf when mounted without -o flock test"
9373
9374 test_105d() { # bug 15924
9375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9376
9377         test_mkdir $DIR/$tdir
9378         flock_is_enabled || skip_env "mount w/o flock enabled"
9379         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9380         $LCTL set_param fail_loc=0x80000315
9381         flocks_test 2 $DIR/$tdir
9382 }
9383 run_test 105d "flock race (should not freeze) ========"
9384
9385 test_105e() { # bug 22660 && 22040
9386         flock_is_enabled || skip_env "mount w/o flock enabled"
9387
9388         touch $DIR/$tfile
9389         flocks_test 3 $DIR/$tfile
9390 }
9391 run_test 105e "Two conflicting flocks from same process"
9392
9393 test_106() { #bug 10921
9394         test_mkdir $DIR/$tdir
9395         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9396         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9397 }
9398 run_test 106 "attempt exec of dir followed by chown of that dir"
9399
9400 test_107() {
9401         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9402
9403         CDIR=`pwd`
9404         local file=core
9405
9406         cd $DIR
9407         rm -f $file
9408
9409         local save_pattern=$(sysctl -n kernel.core_pattern)
9410         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9411         sysctl -w kernel.core_pattern=$file
9412         sysctl -w kernel.core_uses_pid=0
9413
9414         ulimit -c unlimited
9415         sleep 60 &
9416         SLEEPPID=$!
9417
9418         sleep 1
9419
9420         kill -s 11 $SLEEPPID
9421         wait $SLEEPPID
9422         if [ -e $file ]; then
9423                 size=`stat -c%s $file`
9424                 [ $size -eq 0 ] && error "Fail to create core file $file"
9425         else
9426                 error "Fail to create core file $file"
9427         fi
9428         rm -f $file
9429         sysctl -w kernel.core_pattern=$save_pattern
9430         sysctl -w kernel.core_uses_pid=$save_uses_pid
9431         cd $CDIR
9432 }
9433 run_test 107 "Coredump on SIG"
9434
9435 test_110() {
9436         test_mkdir $DIR/$tdir
9437         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9438         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9439                 error "mkdir with 256 char should fail, but did not"
9440         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9441                 error "create with 255 char failed"
9442         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9443                 error "create with 256 char should fail, but did not"
9444
9445         ls -l $DIR/$tdir
9446         rm -rf $DIR/$tdir
9447 }
9448 run_test 110 "filename length checking"
9449
9450 #
9451 # Purpose: To verify dynamic thread (OSS) creation.
9452 #
9453 test_115() {
9454         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9455         remote_ost_nodsh && skip "remote OST with nodsh"
9456
9457         # Lustre does not stop service threads once they are started.
9458         # Reset number of running threads to default.
9459         stopall
9460         setupall
9461
9462         local OSTIO_pre
9463         local save_params="$TMP/sanity-$TESTNAME.parameters"
9464
9465         # Get ll_ost_io count before I/O
9466         OSTIO_pre=$(do_facet ost1 \
9467                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9468         # Exit if lustre is not running (ll_ost_io not running).
9469         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9470
9471         echo "Starting with $OSTIO_pre threads"
9472         local thread_max=$((OSTIO_pre * 2))
9473         local rpc_in_flight=$((thread_max * 2))
9474         # Number of I/O Process proposed to be started.
9475         local nfiles
9476         local facets=$(get_facets OST)
9477
9478         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9479         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9480
9481         # Set in_flight to $rpc_in_flight
9482         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9483                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9484         nfiles=${rpc_in_flight}
9485         # Set ost thread_max to $thread_max
9486         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9487
9488         # 5 Minutes should be sufficient for max number of OSS
9489         # threads(thread_max) to be created.
9490         local timeout=300
9491
9492         # Start I/O.
9493         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9494         test_mkdir $DIR/$tdir
9495         for i in $(seq $nfiles); do
9496                 local file=$DIR/$tdir/${tfile}-$i
9497                 $LFS setstripe -c -1 -i 0 $file
9498                 ($WTL $file $timeout)&
9499         done
9500
9501         # I/O Started - Wait for thread_started to reach thread_max or report
9502         # error if thread_started is more than thread_max.
9503         echo "Waiting for thread_started to reach thread_max"
9504         local thread_started=0
9505         local end_time=$((SECONDS + timeout))
9506
9507         while [ $SECONDS -le $end_time ] ; do
9508                 echo -n "."
9509                 # Get ost i/o thread_started count.
9510                 thread_started=$(do_facet ost1 \
9511                         "$LCTL get_param \
9512                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9513                 # Break out if thread_started is equal/greater than thread_max
9514                 if [[ $thread_started -ge $thread_max ]]; then
9515                         echo ll_ost_io thread_started $thread_started, \
9516                                 equal/greater than thread_max $thread_max
9517                         break
9518                 fi
9519                 sleep 1
9520         done
9521
9522         # Cleanup - We have the numbers, Kill i/o jobs if running.
9523         jobcount=($(jobs -p))
9524         for i in $(seq 0 $((${#jobcount[@]}-1)))
9525         do
9526                 kill -9 ${jobcount[$i]}
9527                 if [ $? -ne 0 ] ; then
9528                         echo Warning: \
9529                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9530                 fi
9531         done
9532
9533         # Cleanup files left by WTL binary.
9534         for i in $(seq $nfiles); do
9535                 local file=$DIR/$tdir/${tfile}-$i
9536                 rm -rf $file
9537                 if [ $? -ne 0 ] ; then
9538                         echo "Warning: Failed to delete file $file"
9539                 fi
9540         done
9541
9542         restore_lustre_params <$save_params
9543         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9544
9545         # Error out if no new thread has started or Thread started is greater
9546         # than thread max.
9547         if [[ $thread_started -le $OSTIO_pre ||
9548                         $thread_started -gt $thread_max ]]; then
9549                 error "ll_ost_io: thread_started $thread_started" \
9550                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9551                       "No new thread started or thread started greater " \
9552                       "than thread_max."
9553         fi
9554 }
9555 run_test 115 "verify dynamic thread creation===================="
9556
9557 free_min_max () {
9558         wait_delete_completed
9559         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9560         echo "OST kbytes available: ${AVAIL[@]}"
9561         MAXV=${AVAIL[0]}
9562         MAXI=0
9563         MINV=${AVAIL[0]}
9564         MINI=0
9565         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9566                 #echo OST $i: ${AVAIL[i]}kb
9567                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9568                         MAXV=${AVAIL[i]}
9569                         MAXI=$i
9570                 fi
9571                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9572                         MINV=${AVAIL[i]}
9573                         MINI=$i
9574                 fi
9575         done
9576         echo "Min free space: OST $MINI: $MINV"
9577         echo "Max free space: OST $MAXI: $MAXV"
9578 }
9579
9580 test_116a() { # was previously test_116()
9581         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9582         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9583         remote_mds_nodsh && skip "remote MDS with nodsh"
9584
9585         echo -n "Free space priority "
9586         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9587                 head -n1
9588         declare -a AVAIL
9589         free_min_max
9590
9591         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9592         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9593         trap simple_cleanup_common EXIT
9594
9595         # Check if we need to generate uneven OSTs
9596         test_mkdir -p $DIR/$tdir/OST${MINI}
9597         local FILL=$((MINV / 4))
9598         local DIFF=$((MAXV - MINV))
9599         local DIFF2=$((DIFF * 100 / MINV))
9600
9601         local threshold=$(do_facet $SINGLEMDS \
9602                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9603         threshold=${threshold%%%}
9604         echo -n "Check for uneven OSTs: "
9605         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9606
9607         if [[ $DIFF2 -gt $threshold ]]; then
9608                 echo "ok"
9609                 echo "Don't need to fill OST$MINI"
9610         else
9611                 # generate uneven OSTs. Write 2% over the QOS threshold value
9612                 echo "no"
9613                 DIFF=$((threshold - DIFF2 + 2))
9614                 DIFF2=$((MINV * DIFF / 100))
9615                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9616                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9617                         error "setstripe failed"
9618                 DIFF=$((DIFF2 / 2048))
9619                 i=0
9620                 while [ $i -lt $DIFF ]; do
9621                         i=$((i + 1))
9622                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9623                                 bs=2M count=1 2>/dev/null
9624                         echo -n .
9625                 done
9626                 echo .
9627                 sync
9628                 sleep_maxage
9629                 free_min_max
9630         fi
9631
9632         DIFF=$((MAXV - MINV))
9633         DIFF2=$((DIFF * 100 / MINV))
9634         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9635         if [ $DIFF2 -gt $threshold ]; then
9636                 echo "ok"
9637         else
9638                 echo "failed - QOS mode won't be used"
9639                 simple_cleanup_common
9640                 skip "QOS imbalance criteria not met"
9641         fi
9642
9643         MINI1=$MINI
9644         MINV1=$MINV
9645         MAXI1=$MAXI
9646         MAXV1=$MAXV
9647
9648         # now fill using QOS
9649         $LFS setstripe -c 1 $DIR/$tdir
9650         FILL=$((FILL / 200))
9651         if [ $FILL -gt 600 ]; then
9652                 FILL=600
9653         fi
9654         echo "writing $FILL files to QOS-assigned OSTs"
9655         i=0
9656         while [ $i -lt $FILL ]; do
9657                 i=$((i + 1))
9658                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9659                         count=1 2>/dev/null
9660                 echo -n .
9661         done
9662         echo "wrote $i 200k files"
9663         sync
9664         sleep_maxage
9665
9666         echo "Note: free space may not be updated, so measurements might be off"
9667         free_min_max
9668         DIFF2=$((MAXV - MINV))
9669         echo "free space delta: orig $DIFF final $DIFF2"
9670         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9671         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9672         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9673         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9674         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9675         if [[ $DIFF -gt 0 ]]; then
9676                 FILL=$((DIFF2 * 100 / DIFF - 100))
9677                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9678         fi
9679
9680         # Figure out which files were written where
9681         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9682                awk '/'$MINI1': / {print $2; exit}')
9683         echo $UUID
9684         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9685         echo "$MINC files created on smaller OST $MINI1"
9686         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9687                awk '/'$MAXI1': / {print $2; exit}')
9688         echo $UUID
9689         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9690         echo "$MAXC files created on larger OST $MAXI1"
9691         if [[ $MINC -gt 0 ]]; then
9692                 FILL=$((MAXC * 100 / MINC - 100))
9693                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9694         fi
9695         [[ $MAXC -gt $MINC ]] ||
9696                 error_ignore LU-9 "stripe QOS didn't balance free space"
9697         simple_cleanup_common
9698 }
9699 run_test 116a "stripe QOS: free space balance ==================="
9700
9701 test_116b() { # LU-2093
9702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9703         remote_mds_nodsh && skip "remote MDS with nodsh"
9704
9705 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9706         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9707                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9708         [ -z "$old_rr" ] && skip "no QOS"
9709         do_facet $SINGLEMDS lctl set_param \
9710                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9711         mkdir -p $DIR/$tdir
9712         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9713         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9714         do_facet $SINGLEMDS lctl set_param fail_loc=0
9715         rm -rf $DIR/$tdir
9716         do_facet $SINGLEMDS lctl set_param \
9717                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9718 }
9719 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9720
9721 test_117() # bug 10891
9722 {
9723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9724
9725         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9726         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9727         lctl set_param fail_loc=0x21e
9728         > $DIR/$tfile || error "truncate failed"
9729         lctl set_param fail_loc=0
9730         echo "Truncate succeeded."
9731         rm -f $DIR/$tfile
9732 }
9733 run_test 117 "verify osd extend =========="
9734
9735 NO_SLOW_RESENDCOUNT=4
9736 export OLD_RESENDCOUNT=""
9737 set_resend_count () {
9738         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9739         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9740         lctl set_param -n $PROC_RESENDCOUNT $1
9741         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9742 }
9743
9744 # for reduce test_118* time (b=14842)
9745 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9746
9747 # Reset async IO behavior after error case
9748 reset_async() {
9749         FILE=$DIR/reset_async
9750
9751         # Ensure all OSCs are cleared
9752         $LFS setstripe -c -1 $FILE
9753         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9754         sync
9755         rm $FILE
9756 }
9757
9758 test_118a() #bug 11710
9759 {
9760         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9761
9762         reset_async
9763
9764         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9765         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9766         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9767
9768         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9769                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9770                 return 1;
9771         fi
9772         rm -f $DIR/$tfile
9773 }
9774 run_test 118a "verify O_SYNC works =========="
9775
9776 test_118b()
9777 {
9778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9779         remote_ost_nodsh && skip "remote OST with nodsh"
9780
9781         reset_async
9782
9783         #define OBD_FAIL_SRV_ENOENT 0x217
9784         set_nodes_failloc "$(osts_nodes)" 0x217
9785         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9786         RC=$?
9787         set_nodes_failloc "$(osts_nodes)" 0
9788         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9789         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9790                     grep -c writeback)
9791
9792         if [[ $RC -eq 0 ]]; then
9793                 error "Must return error due to dropped pages, rc=$RC"
9794                 return 1;
9795         fi
9796
9797         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9798                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9799                 return 1;
9800         fi
9801
9802         echo "Dirty pages not leaked on ENOENT"
9803
9804         # Due to the above error the OSC will issue all RPCs syncronously
9805         # until a subsequent RPC completes successfully without error.
9806         $MULTIOP $DIR/$tfile Ow4096yc
9807         rm -f $DIR/$tfile
9808
9809         return 0
9810 }
9811 run_test 118b "Reclaim dirty pages on fatal error =========="
9812
9813 test_118c()
9814 {
9815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9816
9817         # for 118c, restore the original resend count, LU-1940
9818         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9819                                 set_resend_count $OLD_RESENDCOUNT
9820         remote_ost_nodsh && skip "remote OST with nodsh"
9821
9822         reset_async
9823
9824         #define OBD_FAIL_OST_EROFS               0x216
9825         set_nodes_failloc "$(osts_nodes)" 0x216
9826
9827         # multiop should block due to fsync until pages are written
9828         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9829         MULTIPID=$!
9830         sleep 1
9831
9832         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9833                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9834         fi
9835
9836         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9837                     grep -c writeback)
9838         if [[ $WRITEBACK -eq 0 ]]; then
9839                 error "No page in writeback, writeback=$WRITEBACK"
9840         fi
9841
9842         set_nodes_failloc "$(osts_nodes)" 0
9843         wait $MULTIPID
9844         RC=$?
9845         if [[ $RC -ne 0 ]]; then
9846                 error "Multiop fsync failed, rc=$RC"
9847         fi
9848
9849         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9850         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9851                     grep -c writeback)
9852         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9853                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9854         fi
9855
9856         rm -f $DIR/$tfile
9857         echo "Dirty pages flushed via fsync on EROFS"
9858         return 0
9859 }
9860 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9861
9862 # continue to use small resend count to reduce test_118* time (b=14842)
9863 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9864
9865 test_118d()
9866 {
9867         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9868         remote_ost_nodsh && skip "remote OST with nodsh"
9869
9870         reset_async
9871
9872         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9873         set_nodes_failloc "$(osts_nodes)" 0x214
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         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9890         set_nodes_failloc "$(osts_nodes)" 0
9891
9892         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9893         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9894                     grep -c writeback)
9895         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9896                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9897         fi
9898
9899         rm -f $DIR/$tfile
9900         echo "Dirty pages gaurenteed flushed via fsync"
9901         return 0
9902 }
9903 run_test 118d "Fsync validation inject a delay of the bulk =========="
9904
9905 test_118f() {
9906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9907
9908         reset_async
9909
9910         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9911         lctl set_param fail_loc=0x8000040a
9912
9913         # Should simulate EINVAL error which is fatal
9914         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9915         RC=$?
9916         if [[ $RC -eq 0 ]]; then
9917                 error "Must return error due to dropped pages, rc=$RC"
9918         fi
9919
9920         lctl set_param fail_loc=0x0
9921
9922         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9923         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9924         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9925                     grep -c writeback)
9926         if [[ $LOCKED -ne 0 ]]; then
9927                 error "Locked pages remain in cache, locked=$LOCKED"
9928         fi
9929
9930         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9931                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9932         fi
9933
9934         rm -f $DIR/$tfile
9935         echo "No pages locked after fsync"
9936
9937         reset_async
9938         return 0
9939 }
9940 run_test 118f "Simulate unrecoverable OSC side error =========="
9941
9942 test_118g() {
9943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9944
9945         reset_async
9946
9947         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9948         lctl set_param fail_loc=0x406
9949
9950         # simulate local -ENOMEM
9951         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9952         RC=$?
9953
9954         lctl set_param fail_loc=0
9955         if [[ $RC -eq 0 ]]; then
9956                 error "Must return error due to dropped pages, rc=$RC"
9957         fi
9958
9959         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9960         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9961         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9962                         grep -c writeback)
9963         if [[ $LOCKED -ne 0 ]]; then
9964                 error "Locked pages remain in cache, locked=$LOCKED"
9965         fi
9966
9967         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9968                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9969         fi
9970
9971         rm -f $DIR/$tfile
9972         echo "No pages locked after fsync"
9973
9974         reset_async
9975         return 0
9976 }
9977 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
9978
9979 test_118h() {
9980         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9981         remote_ost_nodsh && skip "remote OST with nodsh"
9982
9983         reset_async
9984
9985         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
9986         set_nodes_failloc "$(osts_nodes)" 0x20e
9987         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
9988         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9989         RC=$?
9990
9991         set_nodes_failloc "$(osts_nodes)" 0
9992         if [[ $RC -eq 0 ]]; then
9993                 error "Must return error due to dropped pages, rc=$RC"
9994         fi
9995
9996         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9997         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9998         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9999                     grep -c writeback)
10000         if [[ $LOCKED -ne 0 ]]; then
10001                 error "Locked pages remain in cache, locked=$LOCKED"
10002         fi
10003
10004         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10005                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10006         fi
10007
10008         rm -f $DIR/$tfile
10009         echo "No pages locked after fsync"
10010
10011         return 0
10012 }
10013 run_test 118h "Verify timeout in handling recoverables errors  =========="
10014
10015 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10016
10017 test_118i() {
10018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10019         remote_ost_nodsh && skip "remote OST with nodsh"
10020
10021         reset_async
10022
10023         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10024         set_nodes_failloc "$(osts_nodes)" 0x20e
10025
10026         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10027         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10028         PID=$!
10029         sleep 5
10030         set_nodes_failloc "$(osts_nodes)" 0
10031
10032         wait $PID
10033         RC=$?
10034         if [[ $RC -ne 0 ]]; then
10035                 error "got error, but should be not, rc=$RC"
10036         fi
10037
10038         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10039         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10040         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10041         if [[ $LOCKED -ne 0 ]]; then
10042                 error "Locked pages remain in cache, locked=$LOCKED"
10043         fi
10044
10045         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10046                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10047         fi
10048
10049         rm -f $DIR/$tfile
10050         echo "No pages locked after fsync"
10051
10052         return 0
10053 }
10054 run_test 118i "Fix error before timeout in recoverable error  =========="
10055
10056 [ "$SLOW" = "no" ] && set_resend_count 4
10057
10058 test_118j() {
10059         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10060         remote_ost_nodsh && skip "remote OST with nodsh"
10061
10062         reset_async
10063
10064         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10065         set_nodes_failloc "$(osts_nodes)" 0x220
10066
10067         # return -EIO from OST
10068         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10069         RC=$?
10070         set_nodes_failloc "$(osts_nodes)" 0x0
10071         if [[ $RC -eq 0 ]]; then
10072                 error "Must return error due to dropped pages, rc=$RC"
10073         fi
10074
10075         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10076         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10077         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10078         if [[ $LOCKED -ne 0 ]]; then
10079                 error "Locked pages remain in cache, locked=$LOCKED"
10080         fi
10081
10082         # in recoverable error on OST we want resend and stay until it finished
10083         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10084                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10085         fi
10086
10087         rm -f $DIR/$tfile
10088         echo "No pages locked after fsync"
10089
10090         return 0
10091 }
10092 run_test 118j "Simulate unrecoverable OST side error =========="
10093
10094 test_118k()
10095 {
10096         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10097         remote_ost_nodsh && skip "remote OSTs with nodsh"
10098
10099         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10100         set_nodes_failloc "$(osts_nodes)" 0x20e
10101         test_mkdir $DIR/$tdir
10102
10103         for ((i=0;i<10;i++)); do
10104                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10105                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10106                 SLEEPPID=$!
10107                 sleep 0.500s
10108                 kill $SLEEPPID
10109                 wait $SLEEPPID
10110         done
10111
10112         set_nodes_failloc "$(osts_nodes)" 0
10113         rm -rf $DIR/$tdir
10114 }
10115 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10116
10117 test_118l() # LU-646
10118 {
10119         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10120
10121         test_mkdir $DIR/$tdir
10122         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10123         rm -rf $DIR/$tdir
10124 }
10125 run_test 118l "fsync dir"
10126
10127 test_118m() # LU-3066
10128 {
10129         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10130
10131         test_mkdir $DIR/$tdir
10132         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10133         rm -rf $DIR/$tdir
10134 }
10135 run_test 118m "fdatasync dir ========="
10136
10137 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10138
10139 test_118n()
10140 {
10141         local begin
10142         local end
10143
10144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10145         remote_ost_nodsh && skip "remote OSTs with nodsh"
10146
10147         # Sleep to avoid a cached response.
10148         #define OBD_STATFS_CACHE_SECONDS 1
10149         sleep 2
10150
10151         # Inject a 10 second delay in the OST_STATFS handler.
10152         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10153         set_nodes_failloc "$(osts_nodes)" 0x242
10154
10155         begin=$SECONDS
10156         stat --file-system $MOUNT > /dev/null
10157         end=$SECONDS
10158
10159         set_nodes_failloc "$(osts_nodes)" 0
10160
10161         if ((end - begin > 20)); then
10162             error "statfs took $((end - begin)) seconds, expected 10"
10163         fi
10164 }
10165 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10166
10167 test_119a() # bug 11737
10168 {
10169         BSIZE=$((512 * 1024))
10170         directio write $DIR/$tfile 0 1 $BSIZE
10171         # We ask to read two blocks, which is more than a file size.
10172         # directio will indicate an error when requested and actual
10173         # sizes aren't equeal (a normal situation in this case) and
10174         # print actual read amount.
10175         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10176         if [ "$NOB" != "$BSIZE" ]; then
10177                 error "read $NOB bytes instead of $BSIZE"
10178         fi
10179         rm -f $DIR/$tfile
10180 }
10181 run_test 119a "Short directIO read must return actual read amount"
10182
10183 test_119b() # bug 11737
10184 {
10185         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10186
10187         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10188         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10189         sync
10190         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10191                 error "direct read failed"
10192         rm -f $DIR/$tfile
10193 }
10194 run_test 119b "Sparse directIO read must return actual read amount"
10195
10196 test_119c() # bug 13099
10197 {
10198         BSIZE=1048576
10199         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10200         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10201         rm -f $DIR/$tfile
10202 }
10203 run_test 119c "Testing for direct read hitting hole"
10204
10205 test_119d() # bug 15950
10206 {
10207         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10208
10209         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10210         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10211         BSIZE=1048576
10212         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10213         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10214         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10215         lctl set_param fail_loc=0x40d
10216         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10217         pid_dio=$!
10218         sleep 1
10219         cat $DIR/$tfile > /dev/null &
10220         lctl set_param fail_loc=0
10221         pid_reads=$!
10222         wait $pid_dio
10223         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10224         sleep 2
10225         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10226         error "the read rpcs have not completed in 2s"
10227         rm -f $DIR/$tfile
10228         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10229 }
10230 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10231
10232 test_120a() {
10233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10234         remote_mds_nodsh && skip "remote MDS with nodsh"
10235         test_mkdir -i0 -c1 $DIR/$tdir
10236         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10237                 skip_env "no early lock cancel on server"
10238
10239         lru_resize_disable mdc
10240         lru_resize_disable osc
10241         cancel_lru_locks mdc
10242         # asynchronous object destroy at MDT could cause bl ast to client
10243         cancel_lru_locks osc
10244
10245         stat $DIR/$tdir > /dev/null
10246         can1=$(do_facet mds1 \
10247                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10248                awk '/ldlm_cancel/ {print $2}')
10249         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10250                awk '/ldlm_bl_callback/ {print $2}')
10251         test_mkdir -i0 -c1 $DIR/$tdir/d1
10252         can2=$(do_facet mds1 \
10253                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10254                awk '/ldlm_cancel/ {print $2}')
10255         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10256                awk '/ldlm_bl_callback/ {print $2}')
10257         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10258         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10259         lru_resize_enable mdc
10260         lru_resize_enable osc
10261 }
10262 run_test 120a "Early Lock Cancel: mkdir test"
10263
10264 test_120b() {
10265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10266         remote_mds_nodsh && skip "remote MDS with nodsh"
10267         test_mkdir $DIR/$tdir
10268         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10269                 skip_env "no early lock cancel on server"
10270
10271         lru_resize_disable mdc
10272         lru_resize_disable osc
10273         cancel_lru_locks mdc
10274         stat $DIR/$tdir > /dev/null
10275         can1=$(do_facet $SINGLEMDS \
10276                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10277                awk '/ldlm_cancel/ {print $2}')
10278         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10279                awk '/ldlm_bl_callback/ {print $2}')
10280         touch $DIR/$tdir/f1
10281         can2=$(do_facet $SINGLEMDS \
10282                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10283                awk '/ldlm_cancel/ {print $2}')
10284         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10285                awk '/ldlm_bl_callback/ {print $2}')
10286         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10287         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10288         lru_resize_enable mdc
10289         lru_resize_enable osc
10290 }
10291 run_test 120b "Early Lock Cancel: create test"
10292
10293 test_120c() {
10294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10295         remote_mds_nodsh && skip "remote MDS with nodsh"
10296         test_mkdir -i0 -c1 $DIR/$tdir
10297         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10298                 skip "no early lock cancel on server"
10299
10300         lru_resize_disable mdc
10301         lru_resize_disable osc
10302         test_mkdir -i0 -c1 $DIR/$tdir/d1
10303         test_mkdir -i0 -c1 $DIR/$tdir/d2
10304         touch $DIR/$tdir/d1/f1
10305         cancel_lru_locks mdc
10306         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10307         can1=$(do_facet mds1 \
10308                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10309                awk '/ldlm_cancel/ {print $2}')
10310         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10311                awk '/ldlm_bl_callback/ {print $2}')
10312         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10313         can2=$(do_facet mds1 \
10314                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10315                awk '/ldlm_cancel/ {print $2}')
10316         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10317                awk '/ldlm_bl_callback/ {print $2}')
10318         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10319         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10320         lru_resize_enable mdc
10321         lru_resize_enable osc
10322 }
10323 run_test 120c "Early Lock Cancel: link test"
10324
10325 test_120d() {
10326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10327         remote_mds_nodsh && skip "remote MDS with nodsh"
10328         test_mkdir -i0 -c1 $DIR/$tdir
10329         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10330                 skip_env "no early lock cancel on server"
10331
10332         lru_resize_disable mdc
10333         lru_resize_disable osc
10334         touch $DIR/$tdir
10335         cancel_lru_locks mdc
10336         stat $DIR/$tdir > /dev/null
10337         can1=$(do_facet mds1 \
10338                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10339                awk '/ldlm_cancel/ {print $2}')
10340         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10341                awk '/ldlm_bl_callback/ {print $2}')
10342         chmod a+x $DIR/$tdir
10343         can2=$(do_facet mds1 \
10344                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10345                awk '/ldlm_cancel/ {print $2}')
10346         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10347                awk '/ldlm_bl_callback/ {print $2}')
10348         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10349         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10350         lru_resize_enable mdc
10351         lru_resize_enable osc
10352 }
10353 run_test 120d "Early Lock Cancel: setattr test"
10354
10355 test_120e() {
10356         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10357         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10358                 skip_env "no early lock cancel on server"
10359         remote_mds_nodsh && skip "remote MDS with nodsh"
10360
10361         local dlmtrace_set=false
10362
10363         test_mkdir -i0 -c1 $DIR/$tdir
10364         lru_resize_disable mdc
10365         lru_resize_disable osc
10366         ! $LCTL get_param debug | grep -q dlmtrace &&
10367                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10368         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10369         cancel_lru_locks mdc
10370         cancel_lru_locks osc
10371         dd if=$DIR/$tdir/f1 of=/dev/null
10372         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10373         # XXX client can not do early lock cancel of OST lock
10374         # during unlink (LU-4206), so cancel osc lock now.
10375         sleep 2
10376         cancel_lru_locks osc
10377         can1=$(do_facet mds1 \
10378                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10379                awk '/ldlm_cancel/ {print $2}')
10380         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10381                awk '/ldlm_bl_callback/ {print $2}')
10382         unlink $DIR/$tdir/f1
10383         sleep 5
10384         can2=$(do_facet mds1 \
10385                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10386                awk '/ldlm_cancel/ {print $2}')
10387         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10388                awk '/ldlm_bl_callback/ {print $2}')
10389         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10390                 $LCTL dk $TMP/cancel.debug.txt
10391         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10392                 $LCTL dk $TMP/blocking.debug.txt
10393         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10394         lru_resize_enable mdc
10395         lru_resize_enable osc
10396 }
10397 run_test 120e "Early Lock Cancel: unlink test"
10398
10399 test_120f() {
10400         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10401         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10402                 skip_env "no early lock cancel on server"
10403         remote_mds_nodsh && skip "remote MDS with nodsh"
10404
10405         test_mkdir -i0 -c1 $DIR/$tdir
10406         lru_resize_disable mdc
10407         lru_resize_disable osc
10408         test_mkdir -i0 -c1 $DIR/$tdir/d1
10409         test_mkdir -i0 -c1 $DIR/$tdir/d2
10410         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10411         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10412         cancel_lru_locks mdc
10413         cancel_lru_locks osc
10414         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10415         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10416         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10417         # XXX client can not do early lock cancel of OST lock
10418         # during rename (LU-4206), so cancel osc lock now.
10419         sleep 2
10420         cancel_lru_locks osc
10421         can1=$(do_facet mds1 \
10422                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10423                awk '/ldlm_cancel/ {print $2}')
10424         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10425                awk '/ldlm_bl_callback/ {print $2}')
10426         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10427         sleep 5
10428         can2=$(do_facet mds1 \
10429                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10430                awk '/ldlm_cancel/ {print $2}')
10431         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10432                awk '/ldlm_bl_callback/ {print $2}')
10433         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10434         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10435         lru_resize_enable mdc
10436         lru_resize_enable osc
10437 }
10438 run_test 120f "Early Lock Cancel: rename test"
10439
10440 test_120g() {
10441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10442         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10443                 skip_env "no early lock cancel on server"
10444         remote_mds_nodsh && skip "remote MDS with nodsh"
10445
10446         lru_resize_disable mdc
10447         lru_resize_disable osc
10448         count=10000
10449         echo create $count files
10450         test_mkdir $DIR/$tdir
10451         cancel_lru_locks mdc
10452         cancel_lru_locks osc
10453         t0=$(date +%s)
10454
10455         can0=$(do_facet $SINGLEMDS \
10456                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10457                awk '/ldlm_cancel/ {print $2}')
10458         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10459                awk '/ldlm_bl_callback/ {print $2}')
10460         createmany -o $DIR/$tdir/f $count
10461         sync
10462         can1=$(do_facet $SINGLEMDS \
10463                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10464                awk '/ldlm_cancel/ {print $2}')
10465         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10466                awk '/ldlm_bl_callback/ {print $2}')
10467         t1=$(date +%s)
10468         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10469         echo rm $count files
10470         rm -r $DIR/$tdir
10471         sync
10472         can2=$(do_facet $SINGLEMDS \
10473                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10474                awk '/ldlm_cancel/ {print $2}')
10475         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10476                awk '/ldlm_bl_callback/ {print $2}')
10477         t2=$(date +%s)
10478         echo total: $count removes in $((t2-t1))
10479         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10480         sleep 2
10481         # wait for commitment of removal
10482         lru_resize_enable mdc
10483         lru_resize_enable osc
10484 }
10485 run_test 120g "Early Lock Cancel: performance test"
10486
10487 test_121() { #bug #10589
10488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10489
10490         rm -rf $DIR/$tfile
10491         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10492 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10493         lctl set_param fail_loc=0x310
10494         cancel_lru_locks osc > /dev/null
10495         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10496         lctl set_param fail_loc=0
10497         [[ $reads -eq $writes ]] ||
10498                 error "read $reads blocks, must be $writes blocks"
10499 }
10500 run_test 121 "read cancel race ========="
10501
10502 test_123a() { # was test 123, statahead(bug 11401)
10503         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10504
10505         SLOWOK=0
10506         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10507                 log "testing UP system. Performance may be lower than expected."
10508                 SLOWOK=1
10509         fi
10510
10511         rm -rf $DIR/$tdir
10512         test_mkdir $DIR/$tdir
10513         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10514         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10515         MULT=10
10516         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10517                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10518
10519                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10520                 lctl set_param -n llite.*.statahead_max 0
10521                 lctl get_param llite.*.statahead_max
10522                 cancel_lru_locks mdc
10523                 cancel_lru_locks osc
10524                 stime=`date +%s`
10525                 time ls -l $DIR/$tdir | wc -l
10526                 etime=`date +%s`
10527                 delta=$((etime - stime))
10528                 log "ls $i files without statahead: $delta sec"
10529                 lctl set_param llite.*.statahead_max=$max
10530
10531                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10532                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10533                 cancel_lru_locks mdc
10534                 cancel_lru_locks osc
10535                 stime=`date +%s`
10536                 time ls -l $DIR/$tdir | wc -l
10537                 etime=`date +%s`
10538                 delta_sa=$((etime - stime))
10539                 log "ls $i files with statahead: $delta_sa sec"
10540                 lctl get_param -n llite.*.statahead_stats
10541                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10542
10543                 [[ $swrong -lt $ewrong ]] &&
10544                         log "statahead was stopped, maybe too many locks held!"
10545                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10546
10547                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10548                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10549                     lctl set_param -n llite.*.statahead_max 0
10550                     lctl get_param llite.*.statahead_max
10551                     cancel_lru_locks mdc
10552                     cancel_lru_locks osc
10553                     stime=`date +%s`
10554                     time ls -l $DIR/$tdir | wc -l
10555                     etime=`date +%s`
10556                     delta=$((etime - stime))
10557                     log "ls $i files again without statahead: $delta sec"
10558                     lctl set_param llite.*.statahead_max=$max
10559                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10560                         if [  $SLOWOK -eq 0 ]; then
10561                                 error "ls $i files is slower with statahead!"
10562                         else
10563                                 log "ls $i files is slower with statahead!"
10564                         fi
10565                         break
10566                     fi
10567                 fi
10568
10569                 [ $delta -gt 20 ] && break
10570                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10571                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10572         done
10573         log "ls done"
10574
10575         stime=`date +%s`
10576         rm -r $DIR/$tdir
10577         sync
10578         etime=`date +%s`
10579         delta=$((etime - stime))
10580         log "rm -r $DIR/$tdir/: $delta seconds"
10581         log "rm done"
10582         lctl get_param -n llite.*.statahead_stats
10583 }
10584 run_test 123a "verify statahead work"
10585
10586 test_123b () { # statahead(bug 15027)
10587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10588
10589         test_mkdir $DIR/$tdir
10590         createmany -o $DIR/$tdir/$tfile-%d 1000
10591
10592         cancel_lru_locks mdc
10593         cancel_lru_locks osc
10594
10595 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10596         lctl set_param fail_loc=0x80000803
10597         ls -lR $DIR/$tdir > /dev/null
10598         log "ls done"
10599         lctl set_param fail_loc=0x0
10600         lctl get_param -n llite.*.statahead_stats
10601         rm -r $DIR/$tdir
10602         sync
10603
10604 }
10605 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10606
10607 test_124a() {
10608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10609         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10610                 skip_env "no lru resize on server"
10611
10612         local NR=2000
10613
10614         test_mkdir $DIR/$tdir
10615
10616         log "create $NR files at $DIR/$tdir"
10617         createmany -o $DIR/$tdir/f $NR ||
10618                 error "failed to create $NR files in $DIR/$tdir"
10619
10620         cancel_lru_locks mdc
10621         ls -l $DIR/$tdir > /dev/null
10622
10623         local NSDIR=""
10624         local LRU_SIZE=0
10625         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10626                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10627                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10628                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10629                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10630                         log "NSDIR=$NSDIR"
10631                         log "NS=$(basename $NSDIR)"
10632                         break
10633                 fi
10634         done
10635
10636         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10637                 skip "Not enough cached locks created!"
10638         fi
10639         log "LRU=$LRU_SIZE"
10640
10641         local SLEEP=30
10642
10643         # We know that lru resize allows one client to hold $LIMIT locks
10644         # for 10h. After that locks begin to be killed by client.
10645         local MAX_HRS=10
10646         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10647         log "LIMIT=$LIMIT"
10648         if [ $LIMIT -lt $LRU_SIZE ]; then
10649                 skip "Limit is too small $LIMIT"
10650         fi
10651
10652         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10653         # killing locks. Some time was spent for creating locks. This means
10654         # that up to the moment of sleep finish we must have killed some of
10655         # them (10-100 locks). This depends on how fast ther were created.
10656         # Many of them were touched in almost the same moment and thus will
10657         # be killed in groups.
10658         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10659
10660         # Use $LRU_SIZE_B here to take into account real number of locks
10661         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10662         local LRU_SIZE_B=$LRU_SIZE
10663         log "LVF=$LVF"
10664         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10665         log "OLD_LVF=$OLD_LVF"
10666         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10667
10668         # Let's make sure that we really have some margin. Client checks
10669         # cached locks every 10 sec.
10670         SLEEP=$((SLEEP+20))
10671         log "Sleep ${SLEEP} sec"
10672         local SEC=0
10673         while ((SEC<$SLEEP)); do
10674                 echo -n "..."
10675                 sleep 5
10676                 SEC=$((SEC+5))
10677                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10678                 echo -n "$LRU_SIZE"
10679         done
10680         echo ""
10681         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10682         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10683
10684         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10685                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10686                 unlinkmany $DIR/$tdir/f $NR
10687                 return
10688         }
10689
10690         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10691         log "unlink $NR files at $DIR/$tdir"
10692         unlinkmany $DIR/$tdir/f $NR
10693 }
10694 run_test 124a "lru resize ======================================="
10695
10696 get_max_pool_limit()
10697 {
10698         local limit=$($LCTL get_param \
10699                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10700         local max=0
10701         for l in $limit; do
10702                 if [[ $l -gt $max ]]; then
10703                         max=$l
10704                 fi
10705         done
10706         echo $max
10707 }
10708
10709 test_124b() {
10710         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10711         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10712                 skip_env "no lru resize on server"
10713
10714         LIMIT=$(get_max_pool_limit)
10715
10716         NR=$(($(default_lru_size)*20))
10717         if [[ $NR -gt $LIMIT ]]; then
10718                 log "Limit lock number by $LIMIT locks"
10719                 NR=$LIMIT
10720         fi
10721
10722         IFree=$(mdsrate_inodes_available)
10723         if [ $IFree -lt $NR ]; then
10724                 log "Limit lock number by $IFree inodes"
10725                 NR=$IFree
10726         fi
10727
10728         lru_resize_disable mdc
10729         test_mkdir -p $DIR/$tdir/disable_lru_resize
10730
10731         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10732         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10733         cancel_lru_locks mdc
10734         stime=`date +%s`
10735         PID=""
10736         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10737         PID="$PID $!"
10738         sleep 2
10739         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10740         PID="$PID $!"
10741         sleep 2
10742         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10743         PID="$PID $!"
10744         wait $PID
10745         etime=`date +%s`
10746         nolruresize_delta=$((etime-stime))
10747         log "ls -la time: $nolruresize_delta seconds"
10748         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10749         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10750
10751         lru_resize_enable mdc
10752         test_mkdir -p $DIR/$tdir/enable_lru_resize
10753
10754         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10755         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10756         cancel_lru_locks mdc
10757         stime=`date +%s`
10758         PID=""
10759         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10760         PID="$PID $!"
10761         sleep 2
10762         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10763         PID="$PID $!"
10764         sleep 2
10765         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10766         PID="$PID $!"
10767         wait $PID
10768         etime=`date +%s`
10769         lruresize_delta=$((etime-stime))
10770         log "ls -la time: $lruresize_delta seconds"
10771         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10772
10773         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10774                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10775         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10776                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10777         else
10778                 log "lru resize performs the same with no lru resize"
10779         fi
10780         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10781 }
10782 run_test 124b "lru resize (performance test) ======================="
10783
10784 test_124c() {
10785         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10786         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10787                 skip_env "no lru resize on server"
10788
10789         # cache ununsed locks on client
10790         local nr=100
10791         cancel_lru_locks mdc
10792         test_mkdir $DIR/$tdir
10793         createmany -o $DIR/$tdir/f $nr ||
10794                 error "failed to create $nr files in $DIR/$tdir"
10795         ls -l $DIR/$tdir > /dev/null
10796
10797         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10798         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10799         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10800         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10801         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10802
10803         # set lru_max_age to 1 sec
10804         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10805         echo "sleep $((recalc_p * 2)) seconds..."
10806         sleep $((recalc_p * 2))
10807
10808         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10809         # restore lru_max_age
10810         $LCTL set_param -n $nsdir.lru_max_age $max_age
10811         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10812         unlinkmany $DIR/$tdir/f $nr
10813 }
10814 run_test 124c "LRUR cancel very aged locks"
10815
10816 test_125() { # 13358
10817         $LCTL get_param -n llite.*.client_type | grep -q local ||
10818                 skip "must run as local client"
10819         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10820                 skip_env "must have acl enabled"
10821         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10822
10823         test_mkdir $DIR/$tdir
10824         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10825         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10826         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10827 }
10828 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10829
10830 test_126() { # bug 12829/13455
10831         $GSS && skip_env "must run as gss disabled"
10832         $LCTL get_param -n llite.*.client_type | grep -q local ||
10833                 skip "must run as local client"
10834         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10835
10836         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10837         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10838         rm -f $DIR/$tfile
10839         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10840 }
10841 run_test 126 "check that the fsgid provided by the client is taken into account"
10842
10843 test_127a() { # bug 15521
10844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10845
10846         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10847         $LCTL set_param osc.*.stats=0
10848         FSIZE=$((2048 * 1024))
10849         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10850         cancel_lru_locks osc
10851         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10852
10853         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10854         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10855                 echo "got $COUNT $NAME"
10856                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10857                 eval $NAME=$COUNT || error "Wrong proc format"
10858
10859                 case $NAME in
10860                         read_bytes|write_bytes)
10861                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10862                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10863                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10864                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10865                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10866                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10867                                 error "sumsquare is too small: $SUMSQ"
10868                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10869                                 error "sumsquare is too big: $SUMSQ"
10870                         ;;
10871                         *) ;;
10872                 esac
10873         done < $DIR/${tfile}.tmp
10874
10875         #check that we actually got some stats
10876         [ "$read_bytes" ] || error "Missing read_bytes stats"
10877         [ "$write_bytes" ] || error "Missing write_bytes stats"
10878         [ "$read_bytes" != 0 ] || error "no read done"
10879         [ "$write_bytes" != 0 ] || error "no write done"
10880 }
10881 run_test 127a "verify the client stats are sane"
10882
10883 test_127b() { # bug LU-333
10884         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10885         local name count samp unit min max sum sumsq
10886
10887         $LCTL set_param llite.*.stats=0
10888
10889         # perform 2 reads and writes so MAX is different from SUM.
10890         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10891         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10892         cancel_lru_locks osc
10893         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10894         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10895
10896         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10897         while read name count samp unit min max sum sumsq; do
10898                 echo "got $count $name"
10899                 eval $name=$count || error "Wrong proc format"
10900
10901                 case $name in
10902                 read_bytes)
10903                         [ $count -ne 2 ] && error "count is not 2: $count"
10904                         [ $min -ne $PAGE_SIZE ] &&
10905                                 error "min is not $PAGE_SIZE: $min"
10906                         [ $max -ne $PAGE_SIZE ] &&
10907                                 error "max is incorrect: $max"
10908                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10909                                 error "sum is wrong: $sum"
10910                         ;;
10911                 write_bytes)
10912                         [ $count -ne 2 ] && error "count is not 2: $count"
10913                         [ $min -ne $PAGE_SIZE ] &&
10914                                 error "min is not $PAGE_SIZE: $min"
10915                         [ $max -ne $PAGE_SIZE ] &&
10916                                 error "max is incorrect: $max"
10917                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10918                                 error "sum is wrong: $sum"
10919                         ;;
10920                 *) ;;
10921                 esac
10922         done < $TMP/$tfile.tmp
10923
10924         #check that we actually got some stats
10925         [ "$read_bytes" ] || error "Missing read_bytes stats"
10926         [ "$write_bytes" ] || error "Missing write_bytes stats"
10927         [ "$read_bytes" != 0 ] || error "no read done"
10928         [ "$write_bytes" != 0 ] || error "no write done"
10929
10930         rm -f $TMP/${tfile}.tmp
10931 }
10932 run_test 127b "verify the llite client stats are sane"
10933
10934 test_128() { # bug 15212
10935         touch $DIR/$tfile
10936         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
10937                 find $DIR/$tfile
10938                 find $DIR/$tfile
10939         EOF
10940
10941         result=$(grep error $TMP/$tfile.log)
10942         rm -f $DIR/$tfile $TMP/$tfile.log
10943         [ -z "$result" ] ||
10944                 error "consecutive find's under interactive lfs failed"
10945 }
10946 run_test 128 "interactive lfs for 2 consecutive find's"
10947
10948 set_dir_limits () {
10949         local mntdev
10950         local canondev
10951         local node
10952
10953         local ldproc=/proc/fs/ldiskfs
10954         local facets=$(get_facets MDS)
10955
10956         for facet in ${facets//,/ }; do
10957                 canondev=$(ldiskfs_canon \
10958                            *.$(convert_facet2label $facet).mntdev $facet)
10959                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
10960                         ldproc=/sys/fs/ldiskfs
10961                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
10962                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
10963         done
10964 }
10965
10966 check_mds_dmesg() {
10967         local facets=$(get_facets MDS)
10968         for facet in ${facets//,/ }; do
10969                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
10970         done
10971         return 1
10972 }
10973
10974 test_129() {
10975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10976         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
10977                 skip "Need MDS version with at least 2.5.56"
10978         if [ "$mds1_FSTYPE" != ldiskfs ]; then
10979                 skip_env "ldiskfs only test"
10980         fi
10981         remote_mds_nodsh && skip "remote MDS with nodsh"
10982
10983         local ENOSPC=28
10984         local EFBIG=27
10985         local has_warning=false
10986
10987         rm -rf $DIR/$tdir
10988         mkdir -p $DIR/$tdir
10989
10990         # block size of mds1
10991         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
10992         set_dir_limits $maxsize $maxsize
10993         local dirsize=$(stat -c%s "$DIR/$tdir")
10994         local nfiles=0
10995         while [[ $dirsize -le $maxsize ]]; do
10996                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
10997                 rc=$?
10998                 if ! $has_warning; then
10999                         check_mds_dmesg '"is approaching"' && has_warning=true
11000                 fi
11001                 # check two errors:
11002                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11003                 # EFBIG for previous versions included in ldiskfs series
11004                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11005                         set_dir_limits 0 0
11006                         echo "return code $rc received as expected"
11007
11008                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11009                                 error_exit "create failed w/o dir size limit"
11010
11011                         check_mds_dmesg '"has reached"' ||
11012                                 error_exit "reached message should be output"
11013
11014                         [ $has_warning = "false" ] &&
11015                                 error_exit "warning message should be output"
11016
11017                         dirsize=$(stat -c%s "$DIR/$tdir")
11018
11019                         [[ $dirsize -ge $maxsize ]] && return 0
11020                         error_exit "current dir size $dirsize, " \
11021                                    "previous limit $maxsize"
11022                 elif [ $rc -ne 0 ]; then
11023                         set_dir_limits 0 0
11024                         error_exit "return $rc received instead of expected " \
11025                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11026                 fi
11027                 nfiles=$((nfiles + 1))
11028                 dirsize=$(stat -c%s "$DIR/$tdir")
11029         done
11030
11031         set_dir_limits 0 0
11032         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11033 }
11034 run_test 129 "test directory size limit ========================"
11035
11036 OLDIFS="$IFS"
11037 cleanup_130() {
11038         trap 0
11039         IFS="$OLDIFS"
11040 }
11041
11042 test_130a() {
11043         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11044         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11045
11046         trap cleanup_130 EXIT RETURN
11047
11048         local fm_file=$DIR/$tfile
11049         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11050         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11051                 error "dd failed for $fm_file"
11052
11053         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11054         filefrag -ves $fm_file
11055         RC=$?
11056         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11057                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11058         [ $RC != 0 ] && error "filefrag $fm_file failed"
11059
11060         filefrag_op=$(filefrag -ve -k $fm_file |
11061                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11062         lun=$($LFS getstripe -i $fm_file)
11063
11064         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11065         IFS=$'\n'
11066         tot_len=0
11067         for line in $filefrag_op
11068         do
11069                 frag_lun=`echo $line | cut -d: -f5`
11070                 ext_len=`echo $line | cut -d: -f4`
11071                 if (( $frag_lun != $lun )); then
11072                         cleanup_130
11073                         error "FIEMAP on 1-stripe file($fm_file) failed"
11074                         return
11075                 fi
11076                 (( tot_len += ext_len ))
11077         done
11078
11079         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11080                 cleanup_130
11081                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11082                 return
11083         fi
11084
11085         cleanup_130
11086
11087         echo "FIEMAP on single striped file succeeded"
11088 }
11089 run_test 130a "FIEMAP (1-stripe file)"
11090
11091 test_130b() {
11092         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11093
11094         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11095         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11096
11097         trap cleanup_130 EXIT RETURN
11098
11099         local fm_file=$DIR/$tfile
11100         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11101                         error "setstripe on $fm_file"
11102         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11103                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11104
11105         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11106                 error "dd failed on $fm_file"
11107
11108         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11109         filefrag_op=$(filefrag -ve -k $fm_file |
11110                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11111
11112         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11113                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11114
11115         IFS=$'\n'
11116         tot_len=0
11117         num_luns=1
11118         for line in $filefrag_op
11119         do
11120                 frag_lun=$(echo $line | cut -d: -f5 |
11121                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11122                 ext_len=$(echo $line | cut -d: -f4)
11123                 if (( $frag_lun != $last_lun )); then
11124                         if (( tot_len != 1024 )); then
11125                                 cleanup_130
11126                                 error "FIEMAP on $fm_file failed; returned " \
11127                                 "len $tot_len for OST $last_lun instead of 1024"
11128                                 return
11129                         else
11130                                 (( num_luns += 1 ))
11131                                 tot_len=0
11132                         fi
11133                 fi
11134                 (( tot_len += ext_len ))
11135                 last_lun=$frag_lun
11136         done
11137         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11138                 cleanup_130
11139                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11140                         "luns or wrong len for OST $last_lun"
11141                 return
11142         fi
11143
11144         cleanup_130
11145
11146         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11147 }
11148 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11149
11150 test_130c() {
11151         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11152
11153         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11154         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11155
11156         trap cleanup_130 EXIT RETURN
11157
11158         local fm_file=$DIR/$tfile
11159         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11160         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11161                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11162
11163         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11164                         error "dd failed on $fm_file"
11165
11166         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11167         filefrag_op=$(filefrag -ve -k $fm_file |
11168                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11169
11170         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11171                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11172
11173         IFS=$'\n'
11174         tot_len=0
11175         num_luns=1
11176         for line in $filefrag_op
11177         do
11178                 frag_lun=$(echo $line | cut -d: -f5 |
11179                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11180                 ext_len=$(echo $line | cut -d: -f4)
11181                 if (( $frag_lun != $last_lun )); then
11182                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11183                         if (( logical != 512 )); then
11184                                 cleanup_130
11185                                 error "FIEMAP on $fm_file failed; returned " \
11186                                 "logical start for lun $logical instead of 512"
11187                                 return
11188                         fi
11189                         if (( tot_len != 512 )); then
11190                                 cleanup_130
11191                                 error "FIEMAP on $fm_file failed; returned " \
11192                                 "len $tot_len for OST $last_lun instead of 1024"
11193                                 return
11194                         else
11195                                 (( num_luns += 1 ))
11196                                 tot_len=0
11197                         fi
11198                 fi
11199                 (( tot_len += ext_len ))
11200                 last_lun=$frag_lun
11201         done
11202         if (( num_luns != 2 || tot_len != 512 )); then
11203                 cleanup_130
11204                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11205                         "luns or wrong len for OST $last_lun"
11206                 return
11207         fi
11208
11209         cleanup_130
11210
11211         echo "FIEMAP on 2-stripe file with hole succeeded"
11212 }
11213 run_test 130c "FIEMAP (2-stripe file with hole)"
11214
11215 test_130d() {
11216         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11217
11218         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11219         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11220
11221         trap cleanup_130 EXIT RETURN
11222
11223         local fm_file=$DIR/$tfile
11224         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11225                         error "setstripe on $fm_file"
11226         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11227                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11228
11229         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11230         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11231                 error "dd failed on $fm_file"
11232
11233         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11234         filefrag_op=$(filefrag -ve -k $fm_file |
11235                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11236
11237         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11238                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11239
11240         IFS=$'\n'
11241         tot_len=0
11242         num_luns=1
11243         for line in $filefrag_op
11244         do
11245                 frag_lun=$(echo $line | cut -d: -f5 |
11246                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11247                 ext_len=$(echo $line | cut -d: -f4)
11248                 if (( $frag_lun != $last_lun )); then
11249                         if (( tot_len != 1024 )); then
11250                                 cleanup_130
11251                                 error "FIEMAP on $fm_file failed; returned " \
11252                                 "len $tot_len for OST $last_lun instead of 1024"
11253                                 return
11254                         else
11255                                 (( num_luns += 1 ))
11256                                 tot_len=0
11257                         fi
11258                 fi
11259                 (( tot_len += ext_len ))
11260                 last_lun=$frag_lun
11261         done
11262         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11263                 cleanup_130
11264                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11265                         "luns or wrong len for OST $last_lun"
11266                 return
11267         fi
11268
11269         cleanup_130
11270
11271         echo "FIEMAP on N-stripe file succeeded"
11272 }
11273 run_test 130d "FIEMAP (N-stripe file)"
11274
11275 test_130e() {
11276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11277
11278         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11279         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11280
11281         trap cleanup_130 EXIT RETURN
11282
11283         local fm_file=$DIR/$tfile
11284         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11285         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11286                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11287
11288         NUM_BLKS=512
11289         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11290         for ((i = 0; i < $NUM_BLKS; i++))
11291         do
11292                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11293         done
11294
11295         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11296         filefrag_op=$(filefrag -ve -k $fm_file |
11297                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11298
11299         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11300                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11301
11302         IFS=$'\n'
11303         tot_len=0
11304         num_luns=1
11305         for line in $filefrag_op
11306         do
11307                 frag_lun=$(echo $line | cut -d: -f5 |
11308                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11309                 ext_len=$(echo $line | cut -d: -f4)
11310                 if (( $frag_lun != $last_lun )); then
11311                         if (( tot_len != $EXPECTED_LEN )); then
11312                                 cleanup_130
11313                                 error "FIEMAP on $fm_file failed; returned " \
11314                                 "len $tot_len for OST $last_lun instead " \
11315                                 "of $EXPECTED_LEN"
11316                                 return
11317                         else
11318                                 (( num_luns += 1 ))
11319                                 tot_len=0
11320                         fi
11321                 fi
11322                 (( tot_len += ext_len ))
11323                 last_lun=$frag_lun
11324         done
11325         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11326                 cleanup_130
11327                 error "FIEMAP on $fm_file failed; returned wrong number " \
11328                         "of luns or wrong len for OST $last_lun"
11329                 return
11330         fi
11331
11332         cleanup_130
11333
11334         echo "FIEMAP with continuation calls succeeded"
11335 }
11336 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11337
11338 test_130f() {
11339         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11340         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11341
11342         local fm_file=$DIR/$tfile
11343         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11344                 error "multiop create with lov_delay_create on $fm_file"
11345
11346         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11347         filefrag_extents=$(filefrag -vek $fm_file |
11348                            awk '/extents? found/ { print $2 }')
11349         if [[ "$filefrag_extents" != "0" ]]; then
11350                 error "FIEMAP on $fm_file failed; " \
11351                       "returned $filefrag_extents expected 0"
11352         fi
11353
11354         rm -f $fm_file
11355 }
11356 run_test 130f "FIEMAP (unstriped file)"
11357
11358 # Test for writev/readv
11359 test_131a() {
11360         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11361                 error "writev test failed"
11362         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11363                 error "readv failed"
11364         rm -f $DIR/$tfile
11365 }
11366 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11367
11368 test_131b() {
11369         local fsize=$((524288 + 1048576 + 1572864))
11370         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11371                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11372                         error "append writev test failed"
11373
11374         ((fsize += 1572864 + 1048576))
11375         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11376                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11377                         error "append writev test failed"
11378         rm -f $DIR/$tfile
11379 }
11380 run_test 131b "test append writev"
11381
11382 test_131c() {
11383         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11384         error "NOT PASS"
11385 }
11386 run_test 131c "test read/write on file w/o objects"
11387
11388 test_131d() {
11389         rwv -f $DIR/$tfile -w -n 1 1572864
11390         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11391         if [ "$NOB" != 1572864 ]; then
11392                 error "Short read filed: read $NOB bytes instead of 1572864"
11393         fi
11394         rm -f $DIR/$tfile
11395 }
11396 run_test 131d "test short read"
11397
11398 test_131e() {
11399         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11400         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11401         error "read hitting hole failed"
11402         rm -f $DIR/$tfile
11403 }
11404 run_test 131e "test read hitting hole"
11405
11406 check_stats() {
11407         local facet=$1
11408         local op=$2
11409         local want=${3:-0}
11410         local res
11411
11412         case $facet in
11413         mds*) res=$(do_facet $facet \
11414                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11415                  ;;
11416         ost*) res=$(do_facet $facet \
11417                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11418                  ;;
11419         *) error "Wrong facet '$facet'" ;;
11420         esac
11421         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11422         # if the argument $3 is zero, it means any stat increment is ok.
11423         if [[ $want -gt 0 ]]; then
11424                 local count=$(echo $res | awk '{ print $2 }')
11425                 [[ $count -ne $want ]] &&
11426                         error "The $op counter on $facet is $count, not $want"
11427         fi
11428 }
11429
11430 test_133a() {
11431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11432         remote_ost_nodsh && skip "remote OST with nodsh"
11433         remote_mds_nodsh && skip "remote MDS with nodsh"
11434         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11435                 skip_env "MDS doesn't support rename stats"
11436
11437         local testdir=$DIR/${tdir}/stats_testdir
11438
11439         mkdir -p $DIR/${tdir}
11440
11441         # clear stats.
11442         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11443         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11444
11445         # verify mdt stats first.
11446         mkdir ${testdir} || error "mkdir failed"
11447         check_stats $SINGLEMDS "mkdir" 1
11448         touch ${testdir}/${tfile} || error "touch failed"
11449         check_stats $SINGLEMDS "open" 1
11450         check_stats $SINGLEMDS "close" 1
11451         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11452                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11453                 check_stats $SINGLEMDS "mknod" 2
11454         }
11455         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11456         check_stats $SINGLEMDS "unlink" 1
11457         rm -f ${testdir}/${tfile} || error "file remove failed"
11458         check_stats $SINGLEMDS "unlink" 2
11459
11460         # remove working dir and check mdt stats again.
11461         rmdir ${testdir} || error "rmdir failed"
11462         check_stats $SINGLEMDS "rmdir" 1
11463
11464         local testdir1=$DIR/${tdir}/stats_testdir1
11465         mkdir -p ${testdir}
11466         mkdir -p ${testdir1}
11467         touch ${testdir1}/test1
11468         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11469         check_stats $SINGLEMDS "crossdir_rename" 1
11470
11471         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11472         check_stats $SINGLEMDS "samedir_rename" 1
11473
11474         rm -rf $DIR/${tdir}
11475 }
11476 run_test 133a "Verifying MDT stats ========================================"
11477
11478 test_133b() {
11479         local res
11480
11481         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11482         remote_ost_nodsh && skip "remote OST with nodsh"
11483         remote_mds_nodsh && skip "remote MDS with nodsh"
11484
11485         local testdir=$DIR/${tdir}/stats_testdir
11486
11487         mkdir -p ${testdir} || error "mkdir failed"
11488         touch ${testdir}/${tfile} || error "touch failed"
11489         cancel_lru_locks mdc
11490
11491         # clear stats.
11492         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11493         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11494
11495         # extra mdt stats verification.
11496         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11497         check_stats $SINGLEMDS "setattr" 1
11498         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11499         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11500         then            # LU-1740
11501                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11502                 check_stats $SINGLEMDS "getattr" 1
11503         fi
11504         rm -rf $DIR/${tdir}
11505
11506         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11507         # so the check below is not reliable
11508         [ $MDSCOUNT -eq 1 ] || return 0
11509
11510         # Sleep to avoid a cached response.
11511         #define OBD_STATFS_CACHE_SECONDS 1
11512         sleep 2
11513         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11514         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11515         $LFS df || error "lfs failed"
11516         check_stats $SINGLEMDS "statfs" 1
11517
11518         # check aggregated statfs (LU-10018)
11519         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11520                 return 0
11521         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11522                 return 0
11523         sleep 2
11524         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11525         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11526         df $DIR
11527         check_stats $SINGLEMDS "statfs" 1
11528
11529         # We want to check that the client didn't send OST_STATFS to
11530         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11531         # extra care is needed here.
11532         if remote_mds; then
11533                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11534                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11535
11536                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11537                 [ "$res" ] && error "OST got STATFS"
11538         fi
11539
11540         return 0
11541 }
11542 run_test 133b "Verifying extra MDT stats =================================="
11543
11544 test_133c() {
11545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11546         remote_ost_nodsh && skip "remote OST with nodsh"
11547         remote_mds_nodsh && skip "remote MDS with nodsh"
11548
11549         local testdir=$DIR/$tdir/stats_testdir
11550
11551         test_mkdir -p $testdir
11552
11553         # verify obdfilter stats.
11554         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11555         sync
11556         cancel_lru_locks osc
11557         wait_delete_completed
11558
11559         # clear stats.
11560         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11561         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11562
11563         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11564                 error "dd failed"
11565         sync
11566         cancel_lru_locks osc
11567         check_stats ost1 "write" 1
11568
11569         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11570         check_stats ost1 "read" 1
11571
11572         > $testdir/$tfile || error "truncate failed"
11573         check_stats ost1 "punch" 1
11574
11575         rm -f $testdir/$tfile || error "file remove failed"
11576         wait_delete_completed
11577         check_stats ost1 "destroy" 1
11578
11579         rm -rf $DIR/$tdir
11580 }
11581 run_test 133c "Verifying OST stats ========================================"
11582
11583 order_2() {
11584         local value=$1
11585         local orig=$value
11586         local order=1
11587
11588         while [ $value -ge 2 ]; do
11589                 order=$((order*2))
11590                 value=$((value/2))
11591         done
11592
11593         if [ $orig -gt $order ]; then
11594                 order=$((order*2))
11595         fi
11596         echo $order
11597 }
11598
11599 size_in_KMGT() {
11600     local value=$1
11601     local size=('K' 'M' 'G' 'T');
11602     local i=0
11603     local size_string=$value
11604
11605     while [ $value -ge 1024 ]; do
11606         if [ $i -gt 3 ]; then
11607             #T is the biggest unit we get here, if that is bigger,
11608             #just return XXXT
11609             size_string=${value}T
11610             break
11611         fi
11612         value=$((value >> 10))
11613         if [ $value -lt 1024 ]; then
11614             size_string=${value}${size[$i]}
11615             break
11616         fi
11617         i=$((i + 1))
11618     done
11619
11620     echo $size_string
11621 }
11622
11623 get_rename_size() {
11624         local size=$1
11625         local context=${2:-.}
11626         local sample=$(do_facet $SINGLEMDS $LCTL \
11627                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11628                 grep -A1 $context |
11629                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11630         echo $sample
11631 }
11632
11633 test_133d() {
11634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11635         remote_ost_nodsh && skip "remote OST with nodsh"
11636         remote_mds_nodsh && skip "remote MDS with nodsh"
11637         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11638                 skip_env "MDS doesn't support rename stats"
11639
11640         local testdir1=$DIR/${tdir}/stats_testdir1
11641         local testdir2=$DIR/${tdir}/stats_testdir2
11642         mkdir -p $DIR/${tdir}
11643
11644         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11645
11646         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11647         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11648
11649         createmany -o $testdir1/test 512 || error "createmany failed"
11650
11651         # check samedir rename size
11652         mv ${testdir1}/test0 ${testdir1}/test_0
11653
11654         local testdir1_size=$(ls -l $DIR/${tdir} |
11655                 awk '/stats_testdir1/ {print $5}')
11656         local testdir2_size=$(ls -l $DIR/${tdir} |
11657                 awk '/stats_testdir2/ {print $5}')
11658
11659         testdir1_size=$(order_2 $testdir1_size)
11660         testdir2_size=$(order_2 $testdir2_size)
11661
11662         testdir1_size=$(size_in_KMGT $testdir1_size)
11663         testdir2_size=$(size_in_KMGT $testdir2_size)
11664
11665         echo "source rename dir size: ${testdir1_size}"
11666         echo "target rename dir size: ${testdir2_size}"
11667
11668         local cmd="do_facet $SINGLEMDS $LCTL "
11669         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11670
11671         eval $cmd || error "$cmd failed"
11672         local samedir=$($cmd | grep 'same_dir')
11673         local same_sample=$(get_rename_size $testdir1_size)
11674         [ -z "$samedir" ] && error "samedir_rename_size count error"
11675         [[ $same_sample -eq 1 ]] ||
11676                 error "samedir_rename_size error $same_sample"
11677         echo "Check same dir rename stats success"
11678
11679         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11680
11681         # check crossdir rename size
11682         mv ${testdir1}/test_0 ${testdir2}/test_0
11683
11684         testdir1_size=$(ls -l $DIR/${tdir} |
11685                 awk '/stats_testdir1/ {print $5}')
11686         testdir2_size=$(ls -l $DIR/${tdir} |
11687                 awk '/stats_testdir2/ {print $5}')
11688
11689         testdir1_size=$(order_2 $testdir1_size)
11690         testdir2_size=$(order_2 $testdir2_size)
11691
11692         testdir1_size=$(size_in_KMGT $testdir1_size)
11693         testdir2_size=$(size_in_KMGT $testdir2_size)
11694
11695         echo "source rename dir size: ${testdir1_size}"
11696         echo "target rename dir size: ${testdir2_size}"
11697
11698         eval $cmd || error "$cmd failed"
11699         local crossdir=$($cmd | grep 'crossdir')
11700         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11701         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11702         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11703         [[ $src_sample -eq 1 ]] ||
11704                 error "crossdir_rename_size error $src_sample"
11705         [[ $tgt_sample -eq 1 ]] ||
11706                 error "crossdir_rename_size error $tgt_sample"
11707         echo "Check cross dir rename stats success"
11708         rm -rf $DIR/${tdir}
11709 }
11710 run_test 133d "Verifying rename_stats ========================================"
11711
11712 test_133e() {
11713         remote_mds_nodsh && skip "remote MDS with nodsh"
11714         remote_ost_nodsh && skip "remote OST with nodsh"
11715         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11716
11717         local testdir=$DIR/${tdir}/stats_testdir
11718         local ctr f0 f1 bs=32768 count=42 sum
11719
11720         mkdir -p ${testdir} || error "mkdir failed"
11721
11722         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11723
11724         for ctr in {write,read}_bytes; do
11725                 sync
11726                 cancel_lru_locks osc
11727
11728                 do_facet ost1 $LCTL set_param -n \
11729                         "obdfilter.*.exports.clear=clear"
11730
11731                 if [ $ctr = write_bytes ]; then
11732                         f0=/dev/zero
11733                         f1=${testdir}/${tfile}
11734                 else
11735                         f0=${testdir}/${tfile}
11736                         f1=/dev/null
11737                 fi
11738
11739                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11740                         error "dd failed"
11741                 sync
11742                 cancel_lru_locks osc
11743
11744                 sum=$(do_facet ost1 $LCTL get_param \
11745                         "obdfilter.*.exports.*.stats" |
11746                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11747                                 $1 == ctr { sum += $7 }
11748                                 END { printf("%0.0f", sum) }')
11749
11750                 if ((sum != bs * count)); then
11751                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11752                 fi
11753         done
11754
11755         rm -rf $DIR/${tdir}
11756 }
11757 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11758
11759 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11760
11761 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11762 # not honor the -ignore_readdir_race option correctly. So we call
11763 # error_ignore() rather than error() in these cases. See LU-11152.
11764 error_133() {
11765         if (find --version; do_facet mds1 find --version) |
11766                 grep -q '\b4\.5\.1[1-4]\b'; then
11767                 error_ignore LU-11152 "$@"
11768         else
11769                 error "$@"
11770         fi
11771 }
11772
11773 test_133f() {
11774         # First without trusting modes.
11775         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11776         echo "proc_dirs='$proc_dirs'"
11777         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11778         find $proc_dirs -exec cat '{}' \; &> /dev/null
11779
11780         # Second verifying readability.
11781         $LCTL get_param -R '*' &> /dev/null
11782
11783         # Verifing writability with badarea_io.
11784         find $proc_dirs \
11785                 -ignore_readdir_race \
11786                 -type f \
11787                 -not -name force_lbug \
11788                 -not -name changelog_mask \
11789                 -exec badarea_io '{}' \; ||
11790                         error_133 "find $proc_dirs failed"
11791 }
11792 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11793
11794 test_133g() {
11795         remote_mds_nodsh && skip "remote MDS with nodsh"
11796         remote_ost_nodsh && skip "remote OST with nodsh"
11797
11798         # eventually, this can also be replaced with "lctl get_param -R",
11799         # but not until that option is always available on the server
11800         local facet
11801         for facet in mds1 ost1; do
11802                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11803                         skip_noexit "Too old lustre on $facet"
11804                 local facet_proc_dirs=$(do_facet $facet \
11805                                         \\\ls -d $proc_regexp 2>/dev/null)
11806                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11807                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11808                 do_facet $facet find $facet_proc_dirs \
11809                         ! -name req_history \
11810                         -exec cat '{}' \\\; &> /dev/null
11811
11812                 do_facet $facet find $facet_proc_dirs \
11813                         ! -name req_history \
11814                         -type f \
11815                         -exec cat '{}' \\\; &> /dev/null ||
11816                                 error "proc file read failed"
11817
11818                 do_facet $facet find $facet_proc_dirs \
11819                         -ignore_readdir_race \
11820                         -type f \
11821                         -not -name force_lbug \
11822                         -not -name changelog_mask \
11823                         -exec badarea_io '{}' \\\; ||
11824                                 error_133 "$facet find $facet_proc_dirs failed"
11825         done
11826
11827         # remount the FS in case writes/reads /proc break the FS
11828         cleanup || error "failed to unmount"
11829         setup || error "failed to setup"
11830         true
11831 }
11832 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11833
11834 test_133h() {
11835         remote_mds_nodsh && skip "remote MDS with nodsh"
11836         remote_ost_nodsh && skip "remote OST with nodsh"
11837         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11838                 skip "Need MDS version at least 2.9.54"
11839
11840         local facet
11841
11842         for facet in client mds1 ost1; do
11843                 local facet_proc_dirs=$(do_facet $facet \
11844                                         \\\ls -d $proc_regexp 2> /dev/null)
11845                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11846                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11847                 # Get the list of files that are missing the terminating newline
11848                 local missing=($(do_facet $facet \
11849                         find ${facet_proc_dirs} -type f \|              \
11850                                 while read F\; do                       \
11851                                         awk -v FS='\v' -v RS='\v\v'     \
11852                                         "'END { if(NR>0 &&              \
11853                                         \\\$NF !~ /.*\\\n\$/)           \
11854                                                 print FILENAME}'"       \
11855                                         '\$F'\;                         \
11856                                 done 2>/dev/null))
11857                 [ ${#missing[*]} -eq 0 ] ||
11858                         error "files do not end with newline: ${missing[*]}"
11859         done
11860 }
11861 run_test 133h "Proc files should end with newlines"
11862
11863 test_134a() {
11864         remote_mds_nodsh && skip "remote MDS with nodsh"
11865         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11866                 skip "Need MDS version at least 2.7.54"
11867
11868         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11869         cancel_lru_locks mdc
11870
11871         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11872         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11873         [ $unused -eq 0 ] || error "$unused locks are not cleared"
11874
11875         local nr=1000
11876         createmany -o $DIR/$tdir/f $nr ||
11877                 error "failed to create $nr files in $DIR/$tdir"
11878         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11879
11880         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
11881         do_facet mds1 $LCTL set_param fail_loc=0x327
11882         do_facet mds1 $LCTL set_param fail_val=500
11883         touch $DIR/$tdir/m
11884
11885         echo "sleep 10 seconds ..."
11886         sleep 10
11887         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
11888
11889         do_facet mds1 $LCTL set_param fail_loc=0
11890         do_facet mds1 $LCTL set_param fail_val=0
11891         [ $lck_cnt -lt $unused ] ||
11892                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
11893
11894         rm $DIR/$tdir/m
11895         unlinkmany $DIR/$tdir/f $nr
11896 }
11897 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
11898
11899 test_134b() {
11900         remote_mds_nodsh && skip "remote MDS with nodsh"
11901         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
11902                 skip "Need MDS version at least 2.7.54"
11903
11904         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
11905         cancel_lru_locks mdc
11906
11907         local low_wm=$(do_facet mds1 $LCTL get_param -n \
11908                         ldlm.lock_reclaim_threshold_mb)
11909         # disable reclaim temporarily
11910         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
11911
11912         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
11913         do_facet mds1 $LCTL set_param fail_loc=0x328
11914         do_facet mds1 $LCTL set_param fail_val=500
11915
11916         $LCTL set_param debug=+trace
11917
11918         local nr=600
11919         createmany -o $DIR/$tdir/f $nr &
11920         local create_pid=$!
11921
11922         echo "Sleep $TIMEOUT seconds ..."
11923         sleep $TIMEOUT
11924         if ! ps -p $create_pid  > /dev/null 2>&1; then
11925                 do_facet mds1 $LCTL set_param fail_loc=0
11926                 do_facet mds1 $LCTL set_param fail_val=0
11927                 do_facet mds1 $LCTL set_param \
11928                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
11929                 error "createmany finished incorrectly!"
11930         fi
11931         do_facet mds1 $LCTL set_param fail_loc=0
11932         do_facet mds1 $LCTL set_param fail_val=0
11933         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
11934         wait $create_pid || return 1
11935
11936         unlinkmany $DIR/$tdir/f $nr
11937 }
11938 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
11939
11940 test_140() { #bug-17379
11941         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11942
11943         test_mkdir $DIR/$tdir
11944         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
11945         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
11946
11947         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
11948         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
11949         local i=0
11950         while i=$((i + 1)); do
11951                 test_mkdir $i
11952                 cd $i || error "Changing to $i"
11953                 ln -s ../stat stat || error "Creating stat symlink"
11954                 # Read the symlink until ELOOP present,
11955                 # not LBUGing the system is considered success,
11956                 # we didn't overrun the stack.
11957                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
11958                 if [ $ret -ne 0 ]; then
11959                         if [ $ret -eq 40 ]; then
11960                                 break  # -ELOOP
11961                         else
11962                                 error "Open stat symlink"
11963                                         return
11964                         fi
11965                 fi
11966         done
11967         i=$((i - 1))
11968         echo "The symlink depth = $i"
11969         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
11970                 error "Invalid symlink depth"
11971
11972         # Test recursive symlink
11973         ln -s symlink_self symlink_self
11974         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
11975         echo "open symlink_self returns $ret"
11976         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
11977 }
11978 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
11979
11980 test_150() {
11981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11982
11983         local TF="$TMP/$tfile"
11984
11985         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
11986         cp $TF $DIR/$tfile
11987         cancel_lru_locks $OSC
11988         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
11989         remount_client $MOUNT
11990         df -P $MOUNT
11991         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
11992
11993         $TRUNCATE $TF 6000
11994         $TRUNCATE $DIR/$tfile 6000
11995         cancel_lru_locks $OSC
11996         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
11997
11998         echo "12345" >>$TF
11999         echo "12345" >>$DIR/$tfile
12000         cancel_lru_locks $OSC
12001         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12002
12003         echo "12345" >>$TF
12004         echo "12345" >>$DIR/$tfile
12005         cancel_lru_locks $OSC
12006         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12007
12008         rm -f $TF
12009         true
12010 }
12011 run_test 150 "truncate/append tests"
12012
12013 #LU-2902 roc_hit was not able to read all values from lproc
12014 function roc_hit_init() {
12015         local list=$(comma_list $(osts_nodes))
12016         local dir=$DIR/$tdir-check
12017         local file=$dir/$tfile
12018         local BEFORE
12019         local AFTER
12020         local idx
12021
12022         test_mkdir $dir
12023         #use setstripe to do a write to every ost
12024         for i in $(seq 0 $((OSTCOUNT-1))); do
12025                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12026                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12027                 idx=$(printf %04x $i)
12028                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12029                         awk '$1 == "cache_access" {sum += $7}
12030                                 END { printf("%0.0f", sum) }')
12031
12032                 cancel_lru_locks osc
12033                 cat $file >/dev/null
12034
12035                 AFTER=$(get_osd_param $list *OST*$idx stats |
12036                         awk '$1 == "cache_access" {sum += $7}
12037                                 END { printf("%0.0f", sum) }')
12038
12039                 echo BEFORE:$BEFORE AFTER:$AFTER
12040                 if ! let "AFTER - BEFORE == 4"; then
12041                         rm -rf $dir
12042                         error "roc_hit is not safe to use"
12043                 fi
12044                 rm $file
12045         done
12046
12047         rm -rf $dir
12048 }
12049
12050 function roc_hit() {
12051         local list=$(comma_list $(osts_nodes))
12052         echo $(get_osd_param $list '' stats |
12053                 awk '$1 == "cache_hit" {sum += $7}
12054                         END { printf("%0.0f", sum) }')
12055 }
12056
12057 function set_cache() {
12058         local on=1
12059
12060         if [ "$2" == "off" ]; then
12061                 on=0;
12062         fi
12063         local list=$(comma_list $(osts_nodes))
12064         set_osd_param $list '' $1_cache_enable $on
12065
12066         cancel_lru_locks osc
12067 }
12068
12069 test_151() {
12070         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12071         remote_ost_nodsh && skip "remote OST with nodsh"
12072
12073         local CPAGES=3
12074         local list=$(comma_list $(osts_nodes))
12075
12076         # check whether obdfilter is cache capable at all
12077         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12078                 skip "not cache-capable obdfilter"
12079         fi
12080
12081         # check cache is enabled on all obdfilters
12082         if get_osd_param $list '' read_cache_enable | grep 0; then
12083                 skip "oss cache is disabled"
12084         fi
12085
12086         set_osd_param $list '' writethrough_cache_enable 1
12087
12088         # check write cache is enabled on all obdfilters
12089         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12090                 skip "oss write cache is NOT enabled"
12091         fi
12092
12093         roc_hit_init
12094
12095         #define OBD_FAIL_OBD_NO_LRU  0x609
12096         do_nodes $list $LCTL set_param fail_loc=0x609
12097
12098         # pages should be in the case right after write
12099         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12100                 error "dd failed"
12101
12102         local BEFORE=$(roc_hit)
12103         cancel_lru_locks osc
12104         cat $DIR/$tfile >/dev/null
12105         local AFTER=$(roc_hit)
12106
12107         do_nodes $list $LCTL set_param fail_loc=0
12108
12109         if ! let "AFTER - BEFORE == CPAGES"; then
12110                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12111         fi
12112
12113         # the following read invalidates the cache
12114         cancel_lru_locks osc
12115         set_osd_param $list '' read_cache_enable 0
12116         cat $DIR/$tfile >/dev/null
12117
12118         # now data shouldn't be found in the cache
12119         BEFORE=$(roc_hit)
12120         cancel_lru_locks osc
12121         cat $DIR/$tfile >/dev/null
12122         AFTER=$(roc_hit)
12123         if let "AFTER - BEFORE != 0"; then
12124                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12125         fi
12126
12127         set_osd_param $list '' read_cache_enable 1
12128         rm -f $DIR/$tfile
12129 }
12130 run_test 151 "test cache on oss and controls ==============================="
12131
12132 test_152() {
12133         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12134
12135         local TF="$TMP/$tfile"
12136
12137         # simulate ENOMEM during write
12138 #define OBD_FAIL_OST_NOMEM      0x226
12139         lctl set_param fail_loc=0x80000226
12140         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12141         cp $TF $DIR/$tfile
12142         sync || error "sync failed"
12143         lctl set_param fail_loc=0
12144
12145         # discard client's cache
12146         cancel_lru_locks osc
12147
12148         # simulate ENOMEM during read
12149         lctl set_param fail_loc=0x80000226
12150         cmp $TF $DIR/$tfile || error "cmp failed"
12151         lctl set_param fail_loc=0
12152
12153         rm -f $TF
12154 }
12155 run_test 152 "test read/write with enomem ============================"
12156
12157 test_153() {
12158         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12159 }
12160 run_test 153 "test if fdatasync does not crash ======================="
12161
12162 dot_lustre_fid_permission_check() {
12163         local fid=$1
12164         local ffid=$MOUNT/.lustre/fid/$fid
12165         local test_dir=$2
12166
12167         echo "stat fid $fid"
12168         stat $ffid > /dev/null || error "stat $ffid failed."
12169         echo "touch fid $fid"
12170         touch $ffid || error "touch $ffid failed."
12171         echo "write to fid $fid"
12172         cat /etc/hosts > $ffid || error "write $ffid failed."
12173         echo "read fid $fid"
12174         diff /etc/hosts $ffid || error "read $ffid failed."
12175         echo "append write to fid $fid"
12176         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12177         echo "rename fid $fid"
12178         mv $ffid $test_dir/$tfile.1 &&
12179                 error "rename $ffid to $tfile.1 should fail."
12180         touch $test_dir/$tfile.1
12181         mv $test_dir/$tfile.1 $ffid &&
12182                 error "rename $tfile.1 to $ffid should fail."
12183         rm -f $test_dir/$tfile.1
12184         echo "truncate fid $fid"
12185         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12186         echo "link fid $fid"
12187         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12188         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12189                 echo "setfacl fid $fid"
12190                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12191                 echo "getfacl fid $fid"
12192                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12193         fi
12194         echo "unlink fid $fid"
12195         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12196         echo "mknod fid $fid"
12197         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12198
12199         fid=[0xf00000400:0x1:0x0]
12200         ffid=$MOUNT/.lustre/fid/$fid
12201
12202         echo "stat non-exist fid $fid"
12203         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12204         echo "write to non-exist fid $fid"
12205         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12206         echo "link new fid $fid"
12207         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12208
12209         mkdir -p $test_dir/$tdir
12210         touch $test_dir/$tdir/$tfile
12211         fid=$($LFS path2fid $test_dir/$tdir)
12212         rc=$?
12213         [ $rc -ne 0 ] &&
12214                 error "error: could not get fid for $test_dir/$dir/$tfile."
12215
12216         ffid=$MOUNT/.lustre/fid/$fid
12217
12218         echo "ls $fid"
12219         ls $ffid > /dev/null || error "ls $ffid failed."
12220         echo "touch $fid/$tfile.1"
12221         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12222
12223         echo "touch $MOUNT/.lustre/fid/$tfile"
12224         touch $MOUNT/.lustre/fid/$tfile && \
12225                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12226
12227         echo "setxattr to $MOUNT/.lustre/fid"
12228         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12229
12230         echo "listxattr for $MOUNT/.lustre/fid"
12231         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12232
12233         echo "delxattr from $MOUNT/.lustre/fid"
12234         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12235
12236         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12237         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12238                 error "touch invalid fid should fail."
12239
12240         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12241         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12242                 error "touch non-normal fid should fail."
12243
12244         echo "rename $tdir to $MOUNT/.lustre/fid"
12245         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12246                 error "rename to $MOUNT/.lustre/fid should fail."
12247
12248         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12249         then            # LU-3547
12250                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12251                 local new_obf_mode=777
12252
12253                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12254                 chmod $new_obf_mode $DIR/.lustre/fid ||
12255                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12256
12257                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12258                 [ $obf_mode -eq $new_obf_mode ] ||
12259                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12260
12261                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12262                 chmod $old_obf_mode $DIR/.lustre/fid ||
12263                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12264         fi
12265
12266         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12267         fid=$($LFS path2fid $test_dir/$tfile-2)
12268
12269         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12270         then # LU-5424
12271                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12272                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12273                         error "create lov data thru .lustre failed"
12274         fi
12275         echo "cp /etc/passwd $test_dir/$tfile-2"
12276         cp /etc/passwd $test_dir/$tfile-2 ||
12277                 error "copy to $test_dir/$tfile-2 failed."
12278         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12279         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12280                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12281
12282         rm -rf $test_dir/tfile.lnk
12283         rm -rf $test_dir/$tfile-2
12284 }
12285
12286 test_154A() {
12287         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12288                 skip "Need MDS version at least 2.4.1"
12289
12290         local tf=$DIR/$tfile
12291         touch $tf
12292
12293         local fid=$($LFS path2fid $tf)
12294         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12295
12296         # check that we get the same pathname back
12297         local found=$($LFS fid2path $MOUNT "$fid")
12298         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12299         [ "$found" == "$tf" ] ||
12300                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12301 }
12302 run_test 154A "lfs path2fid and fid2path basic checks"
12303
12304 test_154B() {
12305         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12306                 skip "Need MDS version at least 2.4.1"
12307
12308         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12309         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12310         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12311         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12312
12313         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12314         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12315
12316         # check that we get the same pathname
12317         echo "PFID: $PFID, name: $name"
12318         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12319         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12320         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12321                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12322
12323         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12324 }
12325 run_test 154B "verify the ll_decode_linkea tool"
12326
12327 test_154a() {
12328         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12329         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12330         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12331                 skip "Need MDS version at least 2.2.51"
12332         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12333
12334         cp /etc/hosts $DIR/$tfile
12335
12336         fid=$($LFS path2fid $DIR/$tfile)
12337         rc=$?
12338         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12339
12340         dot_lustre_fid_permission_check "$fid" $DIR ||
12341                 error "dot lustre permission check $fid failed"
12342
12343         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12344
12345         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12346
12347         touch $MOUNT/.lustre/file &&
12348                 error "creation is not allowed under .lustre"
12349
12350         mkdir $MOUNT/.lustre/dir &&
12351                 error "mkdir is not allowed under .lustre"
12352
12353         rm -rf $DIR/$tfile
12354 }
12355 run_test 154a "Open-by-FID"
12356
12357 test_154b() {
12358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12359         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12360         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12361         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12362                 skip "Need MDS version at least 2.2.51"
12363
12364         local remote_dir=$DIR/$tdir/remote_dir
12365         local MDTIDX=1
12366         local rc=0
12367
12368         mkdir -p $DIR/$tdir
12369         $LFS mkdir -i $MDTIDX $remote_dir ||
12370                 error "create remote directory failed"
12371
12372         cp /etc/hosts $remote_dir/$tfile
12373
12374         fid=$($LFS path2fid $remote_dir/$tfile)
12375         rc=$?
12376         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12377
12378         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12379                 error "dot lustre permission check $fid failed"
12380         rm -rf $DIR/$tdir
12381 }
12382 run_test 154b "Open-by-FID for remote directory"
12383
12384 test_154c() {
12385         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12386                 skip "Need MDS version at least 2.4.1"
12387
12388         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12389         local FID1=$($LFS path2fid $DIR/$tfile.1)
12390         local FID2=$($LFS path2fid $DIR/$tfile.2)
12391         local FID3=$($LFS path2fid $DIR/$tfile.3)
12392
12393         local N=1
12394         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12395                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12396                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12397                 local want=FID$N
12398                 [ "$FID" = "${!want}" ] ||
12399                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12400                 N=$((N + 1))
12401         done
12402
12403         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12404         do
12405                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12406                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12407                 N=$((N + 1))
12408         done
12409 }
12410 run_test 154c "lfs path2fid and fid2path multiple arguments"
12411
12412 test_154d() {
12413         remote_mds_nodsh && skip "remote MDS with nodsh"
12414         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12415                 skip "Need MDS version at least 2.5.53"
12416
12417         if remote_mds; then
12418                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12419         else
12420                 nid="0@lo"
12421         fi
12422         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12423         local fd
12424         local cmd
12425
12426         rm -f $DIR/$tfile
12427         touch $DIR/$tfile
12428
12429         local fid=$($LFS path2fid $DIR/$tfile)
12430         # Open the file
12431         fd=$(free_fd)
12432         cmd="exec $fd<$DIR/$tfile"
12433         eval $cmd
12434         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12435         echo "$fid_list" | grep "$fid"
12436         rc=$?
12437
12438         cmd="exec $fd>/dev/null"
12439         eval $cmd
12440         if [ $rc -ne 0 ]; then
12441                 error "FID $fid not found in open files list $fid_list"
12442         fi
12443 }
12444 run_test 154d "Verify open file fid"
12445
12446 test_154e()
12447 {
12448         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12449                 skip "Need MDS version at least 2.6.50"
12450
12451         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12452                 error ".lustre returned by readdir"
12453         fi
12454 }
12455 run_test 154e ".lustre is not returned by readdir"
12456
12457 test_154f() {
12458         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12459
12460         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12461         test_mkdir -p -c1 $DIR/$tdir/d
12462         # test dirs inherit from its stripe
12463         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12464         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12465         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12466         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12467         touch $DIR/f
12468
12469         # get fid of parents
12470         local FID0=$($LFS path2fid $DIR/$tdir/d)
12471         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12472         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12473         local FID3=$($LFS path2fid $DIR)
12474
12475         # check that path2fid --parents returns expected <parent_fid>/name
12476         # 1) test for a directory (single parent)
12477         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12478         [ "$parent" == "$FID0/foo1" ] ||
12479                 error "expected parent: $FID0/foo1, got: $parent"
12480
12481         # 2) test for a file with nlink > 1 (multiple parents)
12482         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12483         echo "$parent" | grep -F "$FID1/$tfile" ||
12484                 error "$FID1/$tfile not returned in parent list"
12485         echo "$parent" | grep -F "$FID2/link" ||
12486                 error "$FID2/link not returned in parent list"
12487
12488         # 3) get parent by fid
12489         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12490         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12491         echo "$parent" | grep -F "$FID1/$tfile" ||
12492                 error "$FID1/$tfile not returned in parent list (by fid)"
12493         echo "$parent" | grep -F "$FID2/link" ||
12494                 error "$FID2/link not returned in parent list (by fid)"
12495
12496         # 4) test for entry in root directory
12497         parent=$($LFS path2fid --parents $DIR/f)
12498         echo "$parent" | grep -F "$FID3/f" ||
12499                 error "$FID3/f not returned in parent list"
12500
12501         # 5) test it on root directory
12502         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12503                 error "$MOUNT should not have parents"
12504
12505         # enable xattr caching and check that linkea is correctly updated
12506         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12507         save_lustre_params client "llite.*.xattr_cache" > $save
12508         lctl set_param llite.*.xattr_cache 1
12509
12510         # 6.1) linkea update on rename
12511         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12512
12513         # get parents by fid
12514         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12515         # foo1 should no longer be returned in parent list
12516         echo "$parent" | grep -F "$FID1" &&
12517                 error "$FID1 should no longer be in parent list"
12518         # the new path should appear
12519         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12520                 error "$FID2/$tfile.moved is not in parent list"
12521
12522         # 6.2) linkea update on unlink
12523         rm -f $DIR/$tdir/d/foo2/link
12524         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12525         # foo2/link should no longer be returned in parent list
12526         echo "$parent" | grep -F "$FID2/link" &&
12527                 error "$FID2/link should no longer be in parent list"
12528         true
12529
12530         rm -f $DIR/f
12531         restore_lustre_params < $save
12532         rm -f $save
12533 }
12534 run_test 154f "get parent fids by reading link ea"
12535
12536 test_154g()
12537 {
12538         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12539         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12540            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12541                 skip "Need MDS version at least 2.6.92"
12542
12543         mkdir -p $DIR/$tdir
12544         llapi_fid_test -d $DIR/$tdir
12545 }
12546 run_test 154g "various llapi FID tests"
12547
12548 test_155_small_load() {
12549     local temp=$TMP/$tfile
12550     local file=$DIR/$tfile
12551
12552     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12553         error "dd of=$temp bs=6096 count=1 failed"
12554     cp $temp $file
12555     cancel_lru_locks $OSC
12556     cmp $temp $file || error "$temp $file differ"
12557
12558     $TRUNCATE $temp 6000
12559     $TRUNCATE $file 6000
12560     cmp $temp $file || error "$temp $file differ (truncate1)"
12561
12562     echo "12345" >>$temp
12563     echo "12345" >>$file
12564     cmp $temp $file || error "$temp $file differ (append1)"
12565
12566     echo "12345" >>$temp
12567     echo "12345" >>$file
12568     cmp $temp $file || error "$temp $file differ (append2)"
12569
12570     rm -f $temp $file
12571     true
12572 }
12573
12574 test_155_big_load() {
12575         remote_ost_nodsh && skip "remote OST with nodsh"
12576
12577         local temp=$TMP/$tfile
12578         local file=$DIR/$tfile
12579
12580         free_min_max
12581         local cache_size=$(do_facet ost$((MAXI+1)) \
12582                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12583         local large_file_size=$((cache_size * 2))
12584
12585         echo "OSS cache size: $cache_size KB"
12586         echo "Large file size: $large_file_size KB"
12587
12588         [ $MAXV -le $large_file_size ] &&
12589                 skip_env "max available OST size needs > $large_file_size KB"
12590
12591         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12592
12593         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12594                 error "dd of=$temp bs=$large_file_size count=1k failed"
12595         cp $temp $file
12596         ls -lh $temp $file
12597         cancel_lru_locks osc
12598         cmp $temp $file || error "$temp $file differ"
12599
12600         rm -f $temp $file
12601         true
12602 }
12603
12604 save_writethrough() {
12605         local facets=$(get_facets OST)
12606
12607         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12608 }
12609
12610 test_155a() {
12611         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12612
12613         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12614
12615         save_writethrough $p
12616
12617         set_cache read on
12618         set_cache writethrough on
12619         test_155_small_load
12620         restore_lustre_params < $p
12621         rm -f $p
12622 }
12623 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12624
12625 test_155b() {
12626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12627
12628         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12629
12630         save_writethrough $p
12631
12632         set_cache read on
12633         set_cache writethrough off
12634         test_155_small_load
12635         restore_lustre_params < $p
12636         rm -f $p
12637 }
12638 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12639
12640 test_155c() {
12641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12642
12643         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12644
12645         save_writethrough $p
12646
12647         set_cache read off
12648         set_cache writethrough on
12649         test_155_small_load
12650         restore_lustre_params < $p
12651         rm -f $p
12652 }
12653 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12654
12655 test_155d() {
12656         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12657
12658         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12659
12660         save_writethrough $p
12661
12662         set_cache read off
12663         set_cache writethrough off
12664         test_155_small_load
12665         restore_lustre_params < $p
12666         rm -f $p
12667 }
12668 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12669
12670 test_155e() {
12671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12672
12673         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12674
12675         save_writethrough $p
12676
12677         set_cache read on
12678         set_cache writethrough on
12679         test_155_big_load
12680         restore_lustre_params < $p
12681         rm -f $p
12682 }
12683 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12684
12685 test_155f() {
12686         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12687
12688         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12689
12690         save_writethrough $p
12691
12692         set_cache read on
12693         set_cache writethrough off
12694         test_155_big_load
12695         restore_lustre_params < $p
12696         rm -f $p
12697 }
12698 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12699
12700 test_155g() {
12701         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12702
12703         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12704
12705         save_writethrough $p
12706
12707         set_cache read off
12708         set_cache writethrough on
12709         test_155_big_load
12710         restore_lustre_params < $p
12711         rm -f $p
12712 }
12713 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12714
12715 test_155h() {
12716         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12717
12718         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12719
12720         save_writethrough $p
12721
12722         set_cache read off
12723         set_cache writethrough off
12724         test_155_big_load
12725         restore_lustre_params < $p
12726         rm -f $p
12727 }
12728 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12729
12730 test_156() {
12731         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12732         remote_ost_nodsh && skip "remote OST with nodsh"
12733         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12734                 skip "stats not implemented on old servers"
12735         [ "$ost1_FSTYPE" = "zfs" ] &&
12736                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12737
12738         local CPAGES=3
12739         local BEFORE
12740         local AFTER
12741         local file="$DIR/$tfile"
12742         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12743
12744         save_writethrough $p
12745         roc_hit_init
12746
12747         log "Turn on read and write cache"
12748         set_cache read on
12749         set_cache writethrough on
12750
12751         log "Write data and read it back."
12752         log "Read should be satisfied from the cache."
12753         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12754         BEFORE=$(roc_hit)
12755         cancel_lru_locks osc
12756         cat $file >/dev/null
12757         AFTER=$(roc_hit)
12758         if ! let "AFTER - BEFORE == CPAGES"; then
12759                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12760         else
12761                 log "cache hits:: before: $BEFORE, after: $AFTER"
12762         fi
12763
12764         log "Read again; it should be satisfied from the cache."
12765         BEFORE=$AFTER
12766         cancel_lru_locks osc
12767         cat $file >/dev/null
12768         AFTER=$(roc_hit)
12769         if ! let "AFTER - BEFORE == CPAGES"; then
12770                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12771         else
12772                 log "cache hits:: before: $BEFORE, after: $AFTER"
12773         fi
12774
12775         log "Turn off the read cache and turn on the write cache"
12776         set_cache read off
12777         set_cache writethrough on
12778
12779         log "Read again; it should be satisfied from the cache."
12780         BEFORE=$(roc_hit)
12781         cancel_lru_locks osc
12782         cat $file >/dev/null
12783         AFTER=$(roc_hit)
12784         if ! let "AFTER - BEFORE == CPAGES"; then
12785                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12786         else
12787                 log "cache hits:: before: $BEFORE, after: $AFTER"
12788         fi
12789
12790         log "Read again; it should not be satisfied from the cache."
12791         BEFORE=$AFTER
12792         cancel_lru_locks osc
12793         cat $file >/dev/null
12794         AFTER=$(roc_hit)
12795         if ! let "AFTER - BEFORE == 0"; then
12796                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12797         else
12798                 log "cache hits:: before: $BEFORE, after: $AFTER"
12799         fi
12800
12801         log "Write data and read it back."
12802         log "Read should be satisfied from the cache."
12803         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12804         BEFORE=$(roc_hit)
12805         cancel_lru_locks osc
12806         cat $file >/dev/null
12807         AFTER=$(roc_hit)
12808         if ! let "AFTER - BEFORE == CPAGES"; then
12809                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12810         else
12811                 log "cache hits:: before: $BEFORE, after: $AFTER"
12812         fi
12813
12814         log "Read again; it should not be satisfied from the cache."
12815         BEFORE=$AFTER
12816         cancel_lru_locks osc
12817         cat $file >/dev/null
12818         AFTER=$(roc_hit)
12819         if ! let "AFTER - BEFORE == 0"; then
12820                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12821         else
12822                 log "cache hits:: before: $BEFORE, after: $AFTER"
12823         fi
12824
12825         log "Turn off read and write cache"
12826         set_cache read off
12827         set_cache writethrough off
12828
12829         log "Write data and read it back"
12830         log "It should not be satisfied from the cache."
12831         rm -f $file
12832         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12833         cancel_lru_locks osc
12834         BEFORE=$(roc_hit)
12835         cat $file >/dev/null
12836         AFTER=$(roc_hit)
12837         if ! let "AFTER - BEFORE == 0"; then
12838                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12839         else
12840                 log "cache hits:: before: $BEFORE, after: $AFTER"
12841         fi
12842
12843         log "Turn on the read cache and turn off the write cache"
12844         set_cache read on
12845         set_cache writethrough off
12846
12847         log "Write data and read it back"
12848         log "It should not be satisfied from the cache."
12849         rm -f $file
12850         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12851         BEFORE=$(roc_hit)
12852         cancel_lru_locks osc
12853         cat $file >/dev/null
12854         AFTER=$(roc_hit)
12855         if ! let "AFTER - BEFORE == 0"; then
12856                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12857         else
12858                 log "cache hits:: before: $BEFORE, after: $AFTER"
12859         fi
12860
12861         log "Read again; it should be satisfied from the cache."
12862         BEFORE=$(roc_hit)
12863         cancel_lru_locks osc
12864         cat $file >/dev/null
12865         AFTER=$(roc_hit)
12866         if ! let "AFTER - BEFORE == CPAGES"; then
12867                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12868         else
12869                 log "cache hits:: before: $BEFORE, after: $AFTER"
12870         fi
12871
12872         restore_lustre_params < $p
12873         rm -f $p $file
12874 }
12875 run_test 156 "Verification of tunables"
12876
12877 test_160a() {
12878         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12879         remote_mds_nodsh && skip "remote MDS with nodsh"
12880         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
12881                 skip "Need MDS version at least 2.2.0"
12882
12883         changelog_register || error "changelog_register failed"
12884         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
12885         changelog_users $SINGLEMDS | grep -q $cl_user ||
12886                 error "User $cl_user not found in changelog_users"
12887
12888         # change something
12889         test_mkdir -p $DIR/$tdir/pics/2008/zachy
12890         changelog_clear 0 || error "changelog_clear failed"
12891         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
12892         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
12893         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
12894         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
12895         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
12896         rm $DIR/$tdir/pics/desktop.jpg
12897
12898         changelog_dump | tail -10
12899
12900         echo "verifying changelog mask"
12901         changelog_chmask "-MKDIR"
12902         changelog_chmask "-CLOSE"
12903
12904         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
12905         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
12906
12907         changelog_chmask "+MKDIR"
12908         changelog_chmask "+CLOSE"
12909
12910         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
12911         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
12912
12913         changelog_dump | tail -10
12914         MKDIRS=$(changelog_dump | grep -c "MKDIR")
12915         CLOSES=$(changelog_dump | grep -c "CLOSE")
12916         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
12917         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
12918
12919         # verify contents
12920         echo "verifying target fid"
12921         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
12922         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
12923         [ "$fidc" == "$fidf" ] ||
12924                 error "changelog '$tfile' fid $fidc != file fid $fidf"
12925         echo "verifying parent fid"
12926         # The FID returned from the Changelog may be the directory shard on
12927         # a different MDT, and not the FID returned by path2fid on the parent.
12928         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
12929         # since this is what will matter when recreating this file in the tree.
12930         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
12931         local pathp=$($LFS fid2path $MOUNT "$fidp")
12932         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
12933                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
12934
12935         echo "getting records for $cl_user"
12936         changelog_users $SINGLEMDS
12937         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
12938         local nclr=3
12939         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
12940                 error "changelog_clear failed"
12941         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
12942         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
12943         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
12944                 error "user index expect $user_rec1 + $nclr != $user_rec2"
12945
12946         local min0_rec=$(changelog_users $SINGLEMDS |
12947                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
12948         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
12949                           awk '{ print $1; exit; }')
12950
12951         changelog_dump | tail -n 5
12952         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
12953         [ $first_rec == $((min0_rec + 1)) ] ||
12954                 error "first index should be $min0_rec + 1 not $first_rec"
12955
12956         # LU-3446 changelog index reset on MDT restart
12957         local cur_rec1=$(changelog_users $SINGLEMDS |
12958                          awk '/^current.index:/ { print $NF }')
12959         changelog_clear 0 ||
12960                 error "clear all changelog records for $cl_user failed"
12961         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
12962         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
12963                 error "Fail to start $SINGLEMDS"
12964         local cur_rec2=$(changelog_users $SINGLEMDS |
12965                          awk '/^current.index:/ { print $NF }')
12966         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
12967         [ $cur_rec1 == $cur_rec2 ] ||
12968                 error "current index should be $cur_rec1 not $cur_rec2"
12969
12970         echo "verifying users from this test are deregistered"
12971         changelog_deregister || error "changelog_deregister failed"
12972         changelog_users $SINGLEMDS | grep -q $cl_user &&
12973                 error "User '$cl_user' still in changelog_users"
12974
12975         # lctl get_param -n mdd.*.changelog_users
12976         # current index: 144
12977         # ID    index (idle seconds)
12978         # cl3   144 (2)
12979         if ! changelog_users $SINGLEMDS | grep "^cl"; then
12980                 # this is the normal case where all users were deregistered
12981                 # make sure no new records are added when no users are present
12982                 local last_rec1=$(changelog_users $SINGLEMDS |
12983                                   awk '/^current.index:/ { print $NF }')
12984                 touch $DIR/$tdir/chloe
12985                 local last_rec2=$(changelog_users $SINGLEMDS |
12986                                   awk '/^current.index:/ { print $NF }')
12987                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
12988                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
12989         else
12990                 # any changelog users must be leftovers from a previous test
12991                 changelog_users $SINGLEMDS
12992                 echo "other changelog users; can't verify off"
12993         fi
12994 }
12995 run_test 160a "changelog sanity"
12996
12997 test_160b() { # LU-3587
12998         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12999         remote_mds_nodsh && skip "remote MDS with nodsh"
13000         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13001                 skip "Need MDS version at least 2.2.0"
13002
13003         changelog_register || error "changelog_register failed"
13004         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13005         changelog_users $SINGLEMDS | grep -q $cl_user ||
13006                 error "User '$cl_user' not found in changelog_users"
13007
13008         local longname1=$(str_repeat a 255)
13009         local longname2=$(str_repeat b 255)
13010
13011         cd $DIR
13012         echo "creating very long named file"
13013         touch $longname1 || error "create of '$longname1' failed"
13014         echo "renaming very long named file"
13015         mv $longname1 $longname2
13016
13017         changelog_dump | grep RENME | tail -n 5
13018         rm -f $longname2
13019 }
13020 run_test 160b "Verify that very long rename doesn't crash in changelog"
13021
13022 test_160c() {
13023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13024         remote_mds_nodsh && skip "remote MDS with nodsh"
13025
13026         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13027                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13028                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13029                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13030
13031         local rc=0
13032
13033         # Registration step
13034         changelog_register || error "changelog_register failed"
13035
13036         rm -rf $DIR/$tdir
13037         mkdir -p $DIR/$tdir
13038         $MCREATE $DIR/$tdir/foo_160c
13039         changelog_chmask "-TRUNC"
13040         $TRUNCATE $DIR/$tdir/foo_160c 200
13041         changelog_chmask "+TRUNC"
13042         $TRUNCATE $DIR/$tdir/foo_160c 199
13043         changelog_dump | tail -n 5
13044         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13045         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13046 }
13047 run_test 160c "verify that changelog log catch the truncate event"
13048
13049 test_160d() {
13050         remote_mds_nodsh && skip "remote MDS with nodsh"
13051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13052         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13053         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13054                 skip "Need MDS version at least 2.7.60"
13055
13056         # Registration step
13057         changelog_register || error "changelog_register failed"
13058
13059         mkdir -p $DIR/$tdir/migrate_dir
13060         changelog_clear 0 || error "changelog_clear failed"
13061
13062         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13063         changelog_dump | tail -n 5
13064         local migrates=$(changelog_dump | grep -c "MIGRT")
13065         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13066 }
13067 run_test 160d "verify that changelog log catch the migrate event"
13068
13069 test_160e() {
13070         remote_mds_nodsh && skip "remote MDS with nodsh"
13071
13072         # Create a user
13073         changelog_register || error "changelog_register failed"
13074
13075         # Delete a future user (expect fail)
13076         local MDT0=$(facet_svc $SINGLEMDS)
13077         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13078         local rc=$?
13079
13080         if [ $rc -eq 0 ]; then
13081                 error "Deleted non-existant user cl77"
13082         elif [ $rc -ne 2 ]; then
13083                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13084         fi
13085
13086         # Clear to a bad index (1 billion should be safe)
13087         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13088         rc=$?
13089
13090         if [ $rc -eq 0 ]; then
13091                 error "Successfully cleared to invalid CL index"
13092         elif [ $rc -ne 22 ]; then
13093                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13094         fi
13095 }
13096 run_test 160e "changelog negative testing (should return errors)"
13097
13098 test_160f() {
13099         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13100         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13101                 skip "Need MDS version at least 2.10.56"
13102
13103         local mdts=$(comma_list $(mdts_nodes))
13104
13105         # Create a user
13106         changelog_register || error "first changelog_register failed"
13107         changelog_register || error "second changelog_register failed"
13108         local cl_users
13109         declare -A cl_user1
13110         declare -A cl_user2
13111         local user_rec1
13112         local user_rec2
13113         local i
13114
13115         # generate some changelog records to accumulate on each MDT
13116         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13117         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13118                 error "create $DIR/$tdir/$tfile failed"
13119
13120         # check changelogs have been generated
13121         local nbcl=$(changelog_dump | wc -l)
13122         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13123
13124         for param in "changelog_max_idle_time=10" \
13125                      "changelog_gc=1" \
13126                      "changelog_min_gc_interval=2" \
13127                      "changelog_min_free_cat_entries=3"; do
13128                 local MDT0=$(facet_svc $SINGLEMDS)
13129                 local var="${param%=*}"
13130                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13131
13132                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13133                 do_nodes $mdts $LCTL set_param mdd.*.$param
13134         done
13135
13136         # force cl_user2 to be idle (1st part)
13137         sleep 9
13138
13139         # simulate changelog catalog almost full
13140         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13141         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13142
13143         for i in $(seq $MDSCOUNT); do
13144                 cl_users=(${CL_USERS[mds$i]})
13145                 cl_user1[mds$i]="${cl_users[0]}"
13146                 cl_user2[mds$i]="${cl_users[1]}"
13147
13148                 [ -n "${cl_user1[mds$i]}" ] ||
13149                         error "mds$i: no user registered"
13150                 [ -n "${cl_user2[mds$i]}" ] ||
13151                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13152
13153                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13154                 [ -n "$user_rec1" ] ||
13155                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13156                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13157                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13158                 [ -n "$user_rec2" ] ||
13159                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13160                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13161                      "$user_rec1 + 2 == $user_rec2"
13162                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13163                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13164                               "$user_rec1 + 2, but is $user_rec2"
13165                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13166                 [ -n "$user_rec2" ] ||
13167                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13168                 [ $user_rec1 == $user_rec2 ] ||
13169                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13170                               "$user_rec1, but is $user_rec2"
13171         done
13172
13173         # force cl_user2 to be idle (2nd part) and to reach
13174         # changelog_max_idle_time
13175         sleep 2
13176
13177         # generate one more changelog to trigger fail_loc
13178         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13179                 error "create $DIR/$tdir/${tfile}bis failed"
13180
13181         # ensure gc thread is done
13182         for i in $(mdts_nodes); do
13183                 wait_update $i \
13184                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13185                         error "$i: GC-thread not done"
13186         done
13187
13188         local first_rec
13189         for i in $(seq $MDSCOUNT); do
13190                 # check cl_user1 still registered
13191                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13192                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13193                 # check cl_user2 unregistered
13194                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13195                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13196
13197                 # check changelogs are present and starting at $user_rec1 + 1
13198                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13199                 [ -n "$user_rec1" ] ||
13200                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13201                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13202                             awk '{ print $1; exit; }')
13203
13204                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13205                 [ $((user_rec1 + 1)) == $first_rec ] ||
13206                         error "mds$i: first index should be $user_rec1 + 1, " \
13207                               "but is $first_rec"
13208         done
13209 }
13210 run_test 160f "changelog garbage collect (timestamped users)"
13211
13212 test_160g() {
13213         remote_mds_nodsh && skip "remote MDS with nodsh"
13214         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13215                 skip "Need MDS version at least 2.10.56"
13216
13217         local mdts=$(comma_list $(mdts_nodes))
13218
13219         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13220         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13221
13222         # Create a user
13223         changelog_register || error "first changelog_register failed"
13224         changelog_register || error "second changelog_register failed"
13225         local cl_users
13226         declare -A cl_user1
13227         declare -A cl_user2
13228         local user_rec1
13229         local user_rec2
13230         local i
13231
13232         # generate some changelog records to accumulate on each MDT
13233         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13234         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13235                 error "create $DIR/$tdir/$tfile failed"
13236
13237         # check changelogs have been generated
13238         local nbcl=$(changelog_dump | wc -l)
13239         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13240
13241         # reduce the max_idle_indexes value to make sure we exceed it
13242         max_ndx=$((nbcl / 2 - 1))
13243
13244         for param in "changelog_max_idle_indexes=$max_ndx" \
13245                      "changelog_gc=1" \
13246                      "changelog_min_gc_interval=2" \
13247                      "changelog_min_free_cat_entries=3"; do
13248                 local MDT0=$(facet_svc $SINGLEMDS)
13249                 local var="${param%=*}"
13250                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13251
13252                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13253                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13254                         error "unable to set mdd.*.$param"
13255         done
13256
13257         # simulate changelog catalog almost full
13258         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13259         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13260
13261         for i in $(seq $MDSCOUNT); do
13262                 cl_users=(${CL_USERS[mds$i]})
13263                 cl_user1[mds$i]="${cl_users[0]}"
13264                 cl_user2[mds$i]="${cl_users[1]}"
13265
13266                 [ -n "${cl_user1[mds$i]}" ] ||
13267                         error "mds$i: no user registered"
13268                 [ -n "${cl_user2[mds$i]}" ] ||
13269                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13270
13271                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13272                 [ -n "$user_rec1" ] ||
13273                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13274                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13275                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13276                 [ -n "$user_rec2" ] ||
13277                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13278                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13279                      "$user_rec1 + 2 == $user_rec2"
13280                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13281                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13282                               "$user_rec1 + 2, but is $user_rec2"
13283                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13284                 [ -n "$user_rec2" ] ||
13285                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13286                 [ $user_rec1 == $user_rec2 ] ||
13287                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13288                               "$user_rec1, but is $user_rec2"
13289         done
13290
13291         # ensure we are past the previous changelog_min_gc_interval set above
13292         sleep 2
13293
13294         # generate one more changelog to trigger fail_loc
13295         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13296                 error "create $DIR/$tdir/${tfile}bis failed"
13297
13298         # ensure gc thread is done
13299         for i in $(mdts_nodes); do
13300                 wait_update $i \
13301                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13302                         error "$i: GC-thread not done"
13303         done
13304
13305         local first_rec
13306         for i in $(seq $MDSCOUNT); do
13307                 # check cl_user1 still registered
13308                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13309                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13310                 # check cl_user2 unregistered
13311                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13312                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13313
13314                 # check changelogs are present and starting at $user_rec1 + 1
13315                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13316                 [ -n "$user_rec1" ] ||
13317                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13318                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13319                             awk '{ print $1; exit; }')
13320
13321                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13322                 [ $((user_rec1 + 1)) == $first_rec ] ||
13323                         error "mds$i: first index should be $user_rec1 + 1, " \
13324                               "but is $first_rec"
13325         done
13326 }
13327 run_test 160g "changelog garbage collect (old users)"
13328
13329 test_160h() {
13330         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13331         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13332                 skip "Need MDS version at least 2.10.56"
13333
13334         local mdts=$(comma_list $(mdts_nodes))
13335
13336         # Create a user
13337         changelog_register || error "first changelog_register failed"
13338         changelog_register || error "second changelog_register failed"
13339         local cl_users
13340         declare -A cl_user1
13341         declare -A cl_user2
13342         local user_rec1
13343         local user_rec2
13344         local i
13345
13346         # generate some changelog records to accumulate on each MDT
13347         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13348         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13349                 error "create $DIR/$tdir/$tfile failed"
13350
13351         # check changelogs have been generated
13352         local nbcl=$(changelog_dump | wc -l)
13353         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13354
13355         for param in "changelog_max_idle_time=10" \
13356                      "changelog_gc=1" \
13357                      "changelog_min_gc_interval=2"; do
13358                 local MDT0=$(facet_svc $SINGLEMDS)
13359                 local var="${param%=*}"
13360                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13361
13362                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13363                 do_nodes $mdts $LCTL set_param mdd.*.$param
13364         done
13365
13366         # force cl_user2 to be idle (1st part)
13367         sleep 9
13368
13369         for i in $(seq $MDSCOUNT); do
13370                 cl_users=(${CL_USERS[mds$i]})
13371                 cl_user1[mds$i]="${cl_users[0]}"
13372                 cl_user2[mds$i]="${cl_users[1]}"
13373
13374                 [ -n "${cl_user1[mds$i]}" ] ||
13375                         error "mds$i: no user registered"
13376                 [ -n "${cl_user2[mds$i]}" ] ||
13377                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13378
13379                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13380                 [ -n "$user_rec1" ] ||
13381                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13382                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13383                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13384                 [ -n "$user_rec2" ] ||
13385                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13386                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13387                      "$user_rec1 + 2 == $user_rec2"
13388                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13389                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13390                               "$user_rec1 + 2, but is $user_rec2"
13391                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13392                 [ -n "$user_rec2" ] ||
13393                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13394                 [ $user_rec1 == $user_rec2 ] ||
13395                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13396                               "$user_rec1, but is $user_rec2"
13397         done
13398
13399         # force cl_user2 to be idle (2nd part) and to reach
13400         # changelog_max_idle_time
13401         sleep 2
13402
13403         # force each GC-thread start and block then
13404         # one per MDT/MDD, set fail_val accordingly
13405         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13406         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13407
13408         # generate more changelogs to trigger fail_loc
13409         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13410                 error "create $DIR/$tdir/${tfile}bis failed"
13411
13412         # stop MDT to stop GC-thread, should be done in back-ground as it will
13413         # block waiting for the thread to be released and exit
13414         declare -A stop_pids
13415         for i in $(seq $MDSCOUNT); do
13416                 stop mds$i &
13417                 stop_pids[mds$i]=$!
13418         done
13419
13420         for i in $(mdts_nodes); do
13421                 local facet
13422                 local nb=0
13423                 local facets=$(facets_up_on_host $i)
13424
13425                 for facet in ${facets//,/ }; do
13426                         if [[ $facet == mds* ]]; then
13427                                 nb=$((nb + 1))
13428                         fi
13429                 done
13430                 # ensure each MDS's gc threads are still present and all in "R"
13431                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13432                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13433                         error "$i: expected $nb GC-thread"
13434                 wait_update $i \
13435                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13436                         "R" 20 ||
13437                         error "$i: GC-thread not found in R-state"
13438                 # check umounts of each MDT on MDS have reached kthread_stop()
13439                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13440                         error "$i: expected $nb umount"
13441                 wait_update $i \
13442                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13443                         error "$i: umount not found in D-state"
13444         done
13445
13446         # release all GC-threads
13447         do_nodes $mdts $LCTL set_param fail_loc=0
13448
13449         # wait for MDT stop to complete
13450         for i in $(seq $MDSCOUNT); do
13451                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13452         done
13453
13454         # XXX
13455         # may try to check if any orphan changelog records are present
13456         # via ldiskfs/zfs and llog_reader...
13457
13458         # re-start/mount MDTs
13459         for i in $(seq $MDSCOUNT); do
13460                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13461                         error "Fail to start mds$i"
13462         done
13463
13464         local first_rec
13465         for i in $(seq $MDSCOUNT); do
13466                 # check cl_user1 still registered
13467                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13468                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13469                 # check cl_user2 unregistered
13470                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13471                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13472
13473                 # check changelogs are present and starting at $user_rec1 + 1
13474                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13475                 [ -n "$user_rec1" ] ||
13476                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13477                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13478                             awk '{ print $1; exit; }')
13479
13480                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13481                 [ $((user_rec1 + 1)) == $first_rec ] ||
13482                         error "mds$i: first index should be $user_rec1 + 1, " \
13483                               "but is $first_rec"
13484         done
13485 }
13486 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13487               "during mount"
13488
13489 test_160i() {
13490
13491         local mdts=$(comma_list $(mdts_nodes))
13492
13493         changelog_register || error "first changelog_register failed"
13494
13495         # generate some changelog records to accumulate on each MDT
13496         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13497         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13498                 error "create $DIR/$tdir/$tfile failed"
13499
13500         # check changelogs have been generated
13501         local nbcl=$(changelog_dump | wc -l)
13502         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13503
13504         # simulate race between register and unregister
13505         # XXX as fail_loc is set per-MDS, with DNE configs the race
13506         # simulation will only occur for one MDT per MDS and for the
13507         # others the normal race scenario will take place
13508         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13509         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13510         do_nodes $mdts $LCTL set_param fail_val=1
13511
13512         # unregister 1st user
13513         changelog_deregister &
13514         local pid1=$!
13515         # wait some time for deregister work to reach race rdv
13516         sleep 2
13517         # register 2nd user
13518         changelog_register || error "2nd user register failed"
13519
13520         wait $pid1 || error "1st user deregister failed"
13521
13522         local i
13523         local last_rec
13524         declare -A LAST_REC
13525         for i in $(seq $MDSCOUNT); do
13526                 if changelog_users mds$i | grep "^cl"; then
13527                         # make sure new records are added with one user present
13528                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13529                                           awk '/^current.index:/ { print $NF }')
13530                 else
13531                         error "mds$i has no user registered"
13532                 fi
13533         done
13534
13535         # generate more changelog records to accumulate on each MDT
13536         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13537                 error "create $DIR/$tdir/${tfile}bis failed"
13538
13539         for i in $(seq $MDSCOUNT); do
13540                 last_rec=$(changelog_users $SINGLEMDS |
13541                            awk '/^current.index:/ { print $NF }')
13542                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13543                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13544                         error "changelogs are off on mds$i"
13545         done
13546 }
13547 run_test 160i "changelog user register/unregister race"
13548
13549 test_161a() {
13550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13551
13552         test_mkdir -c1 $DIR/$tdir
13553         cp /etc/hosts $DIR/$tdir/$tfile
13554         test_mkdir -c1 $DIR/$tdir/foo1
13555         test_mkdir -c1 $DIR/$tdir/foo2
13556         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13557         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13558         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13559         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13560         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13561         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13562                 $LFS fid2path $DIR $FID
13563                 error "bad link ea"
13564         fi
13565         # middle
13566         rm $DIR/$tdir/foo2/zachary
13567         # last
13568         rm $DIR/$tdir/foo2/thor
13569         # first
13570         rm $DIR/$tdir/$tfile
13571         # rename
13572         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13573         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13574                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13575         rm $DIR/$tdir/foo2/maggie
13576
13577         # overflow the EA
13578         local longname=$tfile.avg_len_is_thirty_two_
13579         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13580                 error_noexit 'failed to unlink many hardlinks'" EXIT
13581         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13582                 error "failed to hardlink many files"
13583         links=$($LFS fid2path $DIR $FID | wc -l)
13584         echo -n "${links}/1000 links in link EA"
13585         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13586 }
13587 run_test 161a "link ea sanity"
13588
13589 test_161b() {
13590         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13591         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13592
13593         local MDTIDX=1
13594         local remote_dir=$DIR/$tdir/remote_dir
13595
13596         mkdir -p $DIR/$tdir
13597         $LFS mkdir -i $MDTIDX $remote_dir ||
13598                 error "create remote directory failed"
13599
13600         cp /etc/hosts $remote_dir/$tfile
13601         mkdir -p $remote_dir/foo1
13602         mkdir -p $remote_dir/foo2
13603         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13604         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13605         ln $remote_dir/$tfile $remote_dir/foo1/luna
13606         ln $remote_dir/$tfile $remote_dir/foo2/thor
13607
13608         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13609                      tr -d ']')
13610         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13611                 $LFS fid2path $DIR $FID
13612                 error "bad link ea"
13613         fi
13614         # middle
13615         rm $remote_dir/foo2/zachary
13616         # last
13617         rm $remote_dir/foo2/thor
13618         # first
13619         rm $remote_dir/$tfile
13620         # rename
13621         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13622         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13623         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13624                 $LFS fid2path $DIR $FID
13625                 error "bad link rename"
13626         fi
13627         rm $remote_dir/foo2/maggie
13628
13629         # overflow the EA
13630         local longname=filename_avg_len_is_thirty_two_
13631         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13632                 error "failed to hardlink many files"
13633         links=$($LFS fid2path $DIR $FID | wc -l)
13634         echo -n "${links}/1000 links in link EA"
13635         [[ ${links} -gt 60 ]] ||
13636                 error "expected at least 60 links in link EA"
13637         unlinkmany $remote_dir/foo2/$longname 1000 ||
13638         error "failed to unlink many hardlinks"
13639 }
13640 run_test 161b "link ea sanity under remote directory"
13641
13642 test_161c() {
13643         remote_mds_nodsh && skip "remote MDS with nodsh"
13644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13645         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13646                 skip "Need MDS version at least 2.1.5"
13647
13648         # define CLF_RENAME_LAST 0x0001
13649         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13650         changelog_register || error "changelog_register failed"
13651
13652         rm -rf $DIR/$tdir
13653         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13654         touch $DIR/$tdir/foo_161c
13655         touch $DIR/$tdir/bar_161c
13656         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13657         changelog_dump | grep RENME | tail -n 5
13658         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13659         changelog_clear 0 || error "changelog_clear failed"
13660         if [ x$flags != "x0x1" ]; then
13661                 error "flag $flags is not 0x1"
13662         fi
13663
13664         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13665         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13666         touch $DIR/$tdir/foo_161c
13667         touch $DIR/$tdir/bar_161c
13668         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13669         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13670         changelog_dump | grep RENME | tail -n 5
13671         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13672         changelog_clear 0 || error "changelog_clear failed"
13673         if [ x$flags != "x0x0" ]; then
13674                 error "flag $flags is not 0x0"
13675         fi
13676         echo "rename overwrite a target having nlink > 1," \
13677                 "changelog record has flags of $flags"
13678
13679         # rename doesn't overwrite a target (changelog flag 0x0)
13680         touch $DIR/$tdir/foo_161c
13681         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13682         changelog_dump | grep RENME | tail -n 5
13683         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13684         changelog_clear 0 || error "changelog_clear failed"
13685         if [ x$flags != "x0x0" ]; then
13686                 error "flag $flags is not 0x0"
13687         fi
13688         echo "rename doesn't overwrite a target," \
13689                 "changelog record has flags of $flags"
13690
13691         # define CLF_UNLINK_LAST 0x0001
13692         # unlink a file having nlink = 1 (changelog flag 0x1)
13693         rm -f $DIR/$tdir/foo2_161c
13694         changelog_dump | grep UNLNK | tail -n 5
13695         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13696         changelog_clear 0 || error "changelog_clear failed"
13697         if [ x$flags != "x0x1" ]; then
13698                 error "flag $flags is not 0x1"
13699         fi
13700         echo "unlink a file having nlink = 1," \
13701                 "changelog record has flags of $flags"
13702
13703         # unlink a file having nlink > 1 (changelog flag 0x0)
13704         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13705         rm -f $DIR/$tdir/foobar_161c
13706         changelog_dump | grep UNLNK | tail -n 5
13707         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13708         changelog_clear 0 || error "changelog_clear failed"
13709         if [ x$flags != "x0x0" ]; then
13710                 error "flag $flags is not 0x0"
13711         fi
13712         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13713 }
13714 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13715
13716 test_161d() {
13717         remote_mds_nodsh && skip "remote MDS with nodsh"
13718         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13719
13720         local pid
13721         local fid
13722
13723         changelog_register || error "changelog_register failed"
13724
13725         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13726         # interfer with $MOUNT/.lustre/fid/ access
13727         mkdir $DIR/$tdir
13728         [[ $? -eq 0 ]] || error "mkdir failed"
13729
13730         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13731         $LCTL set_param fail_loc=0x8000140c
13732         # 5s pause
13733         $LCTL set_param fail_val=5
13734
13735         # create file
13736         echo foofoo > $DIR/$tdir/$tfile &
13737         pid=$!
13738
13739         # wait for create to be delayed
13740         sleep 2
13741
13742         ps -p $pid
13743         [[ $? -eq 0 ]] || error "create should be blocked"
13744
13745         local tempfile=$(mktemp)
13746         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13747         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13748         # some delay may occur during ChangeLog publishing and file read just
13749         # above, that could allow file write to happen finally
13750         [[ -s $tempfile ]] && echo "file should be empty"
13751
13752         $LCTL set_param fail_loc=0
13753
13754         wait $pid
13755         [[ $? -eq 0 ]] || error "create failed"
13756 }
13757 run_test 161d "create with concurrent .lustre/fid access"
13758
13759 check_path() {
13760         local expected="$1"
13761         shift
13762         local fid="$2"
13763
13764         local path
13765         path=$($LFS fid2path "$@")
13766         local rc=$?
13767
13768         if [ $rc -ne 0 ]; then
13769                 error "path looked up of '$expected' failed: rc=$rc"
13770         elif [ "$path" != "$expected" ]; then
13771                 error "path looked up '$path' instead of '$expected'"
13772         else
13773                 echo "FID '$fid' resolves to path '$path' as expected"
13774         fi
13775 }
13776
13777 test_162a() { # was test_162
13778         test_mkdir -p -c1 $DIR/$tdir/d2
13779         touch $DIR/$tdir/d2/$tfile
13780         touch $DIR/$tdir/d2/x1
13781         touch $DIR/$tdir/d2/x2
13782         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13783         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13784         # regular file
13785         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13786         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13787
13788         # softlink
13789         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13790         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13791         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13792
13793         # softlink to wrong file
13794         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13795         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13796         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13797
13798         # hardlink
13799         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13800         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13801         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13802         # fid2path dir/fsname should both work
13803         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13804         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13805
13806         # hardlink count: check that there are 2 links
13807         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13808         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13809
13810         # hardlink indexing: remove the first link
13811         rm $DIR/$tdir/d2/p/q/r/hlink
13812         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13813 }
13814 run_test 162a "path lookup sanity"
13815
13816 test_162b() {
13817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13818         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13819
13820         mkdir $DIR/$tdir
13821         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13822                                 error "create striped dir failed"
13823
13824         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13825                                         tail -n 1 | awk '{print $2}')
13826         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13827
13828         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13829         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13830
13831         # regular file
13832         for ((i=0;i<5;i++)); do
13833                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13834                         error "get fid for f$i failed"
13835                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13836
13837                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13838                         error "get fid for d$i failed"
13839                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13840         done
13841
13842         return 0
13843 }
13844 run_test 162b "striped directory path lookup sanity"
13845
13846 # LU-4239: Verify fid2path works with paths 100 or more directories deep
13847 test_162c() {
13848         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
13849                 skip "Need MDS version at least 2.7.51"
13850
13851         local lpath=$tdir.local
13852         local rpath=$tdir.remote
13853
13854         test_mkdir $DIR/$lpath
13855         test_mkdir $DIR/$rpath
13856
13857         for ((i = 0; i <= 101; i++)); do
13858                 lpath="$lpath/$i"
13859                 mkdir $DIR/$lpath
13860                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
13861                         error "get fid for local directory $DIR/$lpath failed"
13862                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
13863
13864                 rpath="$rpath/$i"
13865                 test_mkdir $DIR/$rpath
13866                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
13867                         error "get fid for remote directory $DIR/$rpath failed"
13868                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
13869         done
13870
13871         return 0
13872 }
13873 run_test 162c "fid2path works with paths 100 or more directories deep"
13874
13875 test_169() {
13876         # do directio so as not to populate the page cache
13877         log "creating a 10 Mb file"
13878         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
13879         log "starting reads"
13880         dd if=$DIR/$tfile of=/dev/null bs=4096 &
13881         log "truncating the file"
13882         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
13883         log "killing dd"
13884         kill %+ || true # reads might have finished
13885         echo "wait until dd is finished"
13886         wait
13887         log "removing the temporary file"
13888         rm -rf $DIR/$tfile || error "tmp file removal failed"
13889 }
13890 run_test 169 "parallel read and truncate should not deadlock"
13891
13892 test_170() {
13893         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13894
13895         $LCTL clear     # bug 18514
13896         $LCTL debug_daemon start $TMP/${tfile}_log_good
13897         touch $DIR/$tfile
13898         $LCTL debug_daemon stop
13899         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
13900                 error "sed failed to read log_good"
13901
13902         $LCTL debug_daemon start $TMP/${tfile}_log_good
13903         rm -rf $DIR/$tfile
13904         $LCTL debug_daemon stop
13905
13906         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
13907                error "lctl df log_bad failed"
13908
13909         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13910         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13911
13912         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
13913         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
13914
13915         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
13916                 error "bad_line good_line1 good_line2 are empty"
13917
13918         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13919         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
13920         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
13921
13922         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
13923         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
13924         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
13925
13926         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
13927                 error "bad_line_new good_line_new are empty"
13928
13929         local expected_good=$((good_line1 + good_line2*2))
13930
13931         rm -f $TMP/${tfile}*
13932         # LU-231, short malformed line may not be counted into bad lines
13933         if [ $bad_line -ne $bad_line_new ] &&
13934                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
13935                 error "expected $bad_line bad lines, but got $bad_line_new"
13936                 return 1
13937         fi
13938
13939         if [ $expected_good -ne $good_line_new ]; then
13940                 error "expected $expected_good good lines, but got $good_line_new"
13941                 return 2
13942         fi
13943         true
13944 }
13945 run_test 170 "test lctl df to handle corrupted log ====================="
13946
13947 test_171() { # bug20592
13948         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13949
13950         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
13951         $LCTL set_param fail_loc=0x50e
13952         $LCTL set_param fail_val=3000
13953         multiop_bg_pause $DIR/$tfile O_s || true
13954         local MULTIPID=$!
13955         kill -USR1 $MULTIPID
13956         # cause log dump
13957         sleep 3
13958         wait $MULTIPID
13959         if dmesg | grep "recursive fault"; then
13960                 error "caught a recursive fault"
13961         fi
13962         $LCTL set_param fail_loc=0
13963         true
13964 }
13965 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
13966
13967 # it would be good to share it with obdfilter-survey/iokit-libecho code
13968 setup_obdecho_osc () {
13969         local rc=0
13970         local ost_nid=$1
13971         local obdfilter_name=$2
13972         echo "Creating new osc for $obdfilter_name on $ost_nid"
13973         # make sure we can find loopback nid
13974         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
13975
13976         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
13977                            ${obdfilter_name}_osc_UUID || rc=2; }
13978         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
13979                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
13980         return $rc
13981 }
13982
13983 cleanup_obdecho_osc () {
13984         local obdfilter_name=$1
13985         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
13986         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
13987         return 0
13988 }
13989
13990 obdecho_test() {
13991         local OBD=$1
13992         local node=$2
13993         local pages=${3:-64}
13994         local rc=0
13995         local id
13996
13997         local count=10
13998         local obd_size=$(get_obd_size $node $OBD)
13999         local page_size=$(get_page_size $node)
14000         if [[ -n "$obd_size" ]]; then
14001                 local new_count=$((obd_size / (pages * page_size / 1024)))
14002                 [[ $new_count -ge $count ]] || count=$new_count
14003         fi
14004
14005         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14006         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14007                            rc=2; }
14008         if [ $rc -eq 0 ]; then
14009             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14010             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14011         fi
14012         echo "New object id is $id"
14013         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14014                            rc=4; }
14015         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14016                            "test_brw $count w v $pages $id" || rc=4; }
14017         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14018                            rc=4; }
14019         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14020                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14021         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14022                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14023         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14024         return $rc
14025 }
14026
14027 test_180a() {
14028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14029
14030         if ! module_loaded obdecho; then
14031                 load_module obdecho/obdecho &&
14032                         stack_trap "rmmod obdecho" EXIT ||
14033                         error "unable to load obdecho on client"
14034         fi
14035
14036         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14037         local host=$($LCTL get_param -n osc.$osc.import |
14038                      awk '/current_connection:/ { print $2 }' )
14039         local target=$($LCTL get_param -n osc.$osc.import |
14040                        awk '/target:/ { print $2 }' )
14041         target=${target%_UUID}
14042
14043         if [ -n "$target" ]; then
14044                 setup_obdecho_osc $host $target &&
14045                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14046                         { error "obdecho setup failed with $?"; return; }
14047
14048                 obdecho_test ${target}_osc client ||
14049                         error "obdecho_test failed on ${target}_osc"
14050         else
14051                 $LCTL get_param osc.$osc.import
14052                 error "there is no osc.$osc.import target"
14053         fi
14054 }
14055 run_test 180a "test obdecho on osc"
14056
14057 test_180b() {
14058         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14059         remote_ost_nodsh && skip "remote OST with nodsh"
14060
14061         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14062                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14063                 error "failed to load module obdecho"
14064
14065         local target=$(do_facet ost1 $LCTL dl |
14066                        awk '/obdfilter/ { print $4; exit; }')
14067
14068         if [ -n "$target" ]; then
14069                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14070         else
14071                 do_facet ost1 $LCTL dl
14072                 error "there is no obdfilter target on ost1"
14073         fi
14074 }
14075 run_test 180b "test obdecho directly on obdfilter"
14076
14077 test_180c() { # LU-2598
14078         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14079         remote_ost_nodsh && skip "remote OST with nodsh"
14080         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14081                 skip "Need MDS version at least 2.4.0"
14082
14083         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14084                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14085                 error "failed to load module obdecho"
14086
14087         local target=$(do_facet ost1 $LCTL dl |
14088                        awk '/obdfilter/ { print $4; exit; }')
14089
14090         if [ -n "$target" ]; then
14091                 local pages=16384 # 64MB bulk I/O RPC size
14092
14093                 obdecho_test "$target" ost1 "$pages" ||
14094                         error "obdecho_test with pages=$pages failed with $?"
14095         else
14096                 do_facet ost1 $LCTL dl
14097                 error "there is no obdfilter target on ost1"
14098         fi
14099 }
14100 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14101
14102 test_181() { # bug 22177
14103         test_mkdir $DIR/$tdir
14104         # create enough files to index the directory
14105         createmany -o $DIR/$tdir/foobar 4000
14106         # print attributes for debug purpose
14107         lsattr -d .
14108         # open dir
14109         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14110         MULTIPID=$!
14111         # remove the files & current working dir
14112         unlinkmany $DIR/$tdir/foobar 4000
14113         rmdir $DIR/$tdir
14114         kill -USR1 $MULTIPID
14115         wait $MULTIPID
14116         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14117         return 0
14118 }
14119 run_test 181 "Test open-unlinked dir ========================"
14120
14121 test_182() {
14122         local fcount=1000
14123         local tcount=10
14124
14125         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14126
14127         $LCTL set_param mdc.*.rpc_stats=clear
14128
14129         for (( i = 0; i < $tcount; i++ )) ; do
14130                 mkdir $DIR/$tdir/$i
14131         done
14132
14133         for (( i = 0; i < $tcount; i++ )) ; do
14134                 createmany -o $DIR/$tdir/$i/f- $fcount &
14135         done
14136         wait
14137
14138         for (( i = 0; i < $tcount; i++ )) ; do
14139                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14140         done
14141         wait
14142
14143         $LCTL get_param mdc.*.rpc_stats
14144
14145         rm -rf $DIR/$tdir
14146 }
14147 run_test 182 "Test parallel modify metadata operations ================"
14148
14149 test_183() { # LU-2275
14150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14151         remote_mds_nodsh && skip "remote MDS with nodsh"
14152         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14153                 skip "Need MDS version at least 2.3.56"
14154
14155         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14156         echo aaa > $DIR/$tdir/$tfile
14157
14158 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14159         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14160
14161         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14162         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14163
14164         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14165
14166         # Flush negative dentry cache
14167         touch $DIR/$tdir/$tfile
14168
14169         # We are not checking for any leaked references here, they'll
14170         # become evident next time we do cleanup with module unload.
14171         rm -rf $DIR/$tdir
14172 }
14173 run_test 183 "No crash or request leak in case of strange dispositions ========"
14174
14175 # test suite 184 is for LU-2016, LU-2017
14176 test_184a() {
14177         check_swap_layouts_support
14178
14179         dir0=$DIR/$tdir/$testnum
14180         test_mkdir -p -c1 $dir0
14181         ref1=/etc/passwd
14182         ref2=/etc/group
14183         file1=$dir0/f1
14184         file2=$dir0/f2
14185         $LFS setstripe -c1 $file1
14186         cp $ref1 $file1
14187         $LFS setstripe -c2 $file2
14188         cp $ref2 $file2
14189         gen1=$($LFS getstripe -g $file1)
14190         gen2=$($LFS getstripe -g $file2)
14191
14192         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14193         gen=$($LFS getstripe -g $file1)
14194         [[ $gen1 != $gen ]] ||
14195                 "Layout generation on $file1 does not change"
14196         gen=$($LFS getstripe -g $file2)
14197         [[ $gen2 != $gen ]] ||
14198                 "Layout generation on $file2 does not change"
14199
14200         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14201         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14202
14203         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14204 }
14205 run_test 184a "Basic layout swap"
14206
14207 test_184b() {
14208         check_swap_layouts_support
14209
14210         dir0=$DIR/$tdir/$testnum
14211         mkdir -p $dir0 || error "creating dir $dir0"
14212         file1=$dir0/f1
14213         file2=$dir0/f2
14214         file3=$dir0/f3
14215         dir1=$dir0/d1
14216         dir2=$dir0/d2
14217         mkdir $dir1 $dir2
14218         $LFS setstripe -c1 $file1
14219         $LFS setstripe -c2 $file2
14220         $LFS setstripe -c1 $file3
14221         chown $RUNAS_ID $file3
14222         gen1=$($LFS getstripe -g $file1)
14223         gen2=$($LFS getstripe -g $file2)
14224
14225         $LFS swap_layouts $dir1 $dir2 &&
14226                 error "swap of directories layouts should fail"
14227         $LFS swap_layouts $dir1 $file1 &&
14228                 error "swap of directory and file layouts should fail"
14229         $RUNAS $LFS swap_layouts $file1 $file2 &&
14230                 error "swap of file we cannot write should fail"
14231         $LFS swap_layouts $file1 $file3 &&
14232                 error "swap of file with different owner should fail"
14233         /bin/true # to clear error code
14234 }
14235 run_test 184b "Forbidden layout swap (will generate errors)"
14236
14237 test_184c() {
14238         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14239         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14240         check_swap_layouts_support
14241
14242         local dir0=$DIR/$tdir/$testnum
14243         mkdir -p $dir0 || error "creating dir $dir0"
14244
14245         local ref1=$dir0/ref1
14246         local ref2=$dir0/ref2
14247         local file1=$dir0/file1
14248         local file2=$dir0/file2
14249         # create a file large enough for the concurrent test
14250         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14251         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14252         echo "ref file size: ref1($(stat -c %s $ref1))," \
14253              "ref2($(stat -c %s $ref2))"
14254
14255         cp $ref2 $file2
14256         dd if=$ref1 of=$file1 bs=16k &
14257         local DD_PID=$!
14258
14259         # Make sure dd starts to copy file
14260         while [ ! -f $file1 ]; do sleep 0.1; done
14261
14262         $LFS swap_layouts $file1 $file2
14263         local rc=$?
14264         wait $DD_PID
14265         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14266         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14267
14268         # how many bytes copied before swapping layout
14269         local copied=$(stat -c %s $file2)
14270         local remaining=$(stat -c %s $ref1)
14271         remaining=$((remaining - copied))
14272         echo "Copied $copied bytes before swapping layout..."
14273
14274         cmp -n $copied $file1 $ref2 | grep differ &&
14275                 error "Content mismatch [0, $copied) of ref2 and file1"
14276         cmp -n $copied $file2 $ref1 ||
14277                 error "Content mismatch [0, $copied) of ref1 and file2"
14278         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14279                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14280
14281         # clean up
14282         rm -f $ref1 $ref2 $file1 $file2
14283 }
14284 run_test 184c "Concurrent write and layout swap"
14285
14286 test_184d() {
14287         check_swap_layouts_support
14288         [ -z "$(which getfattr 2>/dev/null)" ] &&
14289                 skip_env "no getfattr command"
14290
14291         local file1=$DIR/$tdir/$tfile-1
14292         local file2=$DIR/$tdir/$tfile-2
14293         local file3=$DIR/$tdir/$tfile-3
14294         local lovea1
14295         local lovea2
14296
14297         mkdir -p $DIR/$tdir
14298         touch $file1 || error "create $file1 failed"
14299         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14300                 error "create $file2 failed"
14301         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14302                 error "create $file3 failed"
14303         lovea1=$(get_layout_param $file1)
14304
14305         $LFS swap_layouts $file2 $file3 ||
14306                 error "swap $file2 $file3 layouts failed"
14307         $LFS swap_layouts $file1 $file2 ||
14308                 error "swap $file1 $file2 layouts failed"
14309
14310         lovea2=$(get_layout_param $file2)
14311         echo "$lovea1"
14312         echo "$lovea2"
14313         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14314
14315         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14316         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14317 }
14318 run_test 184d "allow stripeless layouts swap"
14319
14320 test_184e() {
14321         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14322                 skip "Need MDS version at least 2.6.94"
14323         check_swap_layouts_support
14324         [ -z "$(which getfattr 2>/dev/null)" ] &&
14325                 skip_env "no getfattr command"
14326
14327         local file1=$DIR/$tdir/$tfile-1
14328         local file2=$DIR/$tdir/$tfile-2
14329         local file3=$DIR/$tdir/$tfile-3
14330         local lovea
14331
14332         mkdir -p $DIR/$tdir
14333         touch $file1 || error "create $file1 failed"
14334         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14335                 error "create $file2 failed"
14336         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14337                 error "create $file3 failed"
14338
14339         $LFS swap_layouts $file1 $file2 ||
14340                 error "swap $file1 $file2 layouts failed"
14341
14342         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14343         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14344
14345         echo 123 > $file1 || error "Should be able to write into $file1"
14346
14347         $LFS swap_layouts $file1 $file3 ||
14348                 error "swap $file1 $file3 layouts failed"
14349
14350         echo 123 > $file1 || error "Should be able to write into $file1"
14351
14352         rm -rf $file1 $file2 $file3
14353 }
14354 run_test 184e "Recreate layout after stripeless layout swaps"
14355
14356 test_184f() {
14357         # Create a file with name longer than sizeof(struct stat) ==
14358         # 144 to see if we can get chars from the file name to appear
14359         # in the returned striping. Note that 'f' == 0x66.
14360         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14361
14362         mkdir -p $DIR/$tdir
14363         mcreate $DIR/$tdir/$file
14364         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14365                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14366         fi
14367 }
14368 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14369
14370 test_185() { # LU-2441
14371         # LU-3553 - no volatile file support in old servers
14372         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14373                 skip "Need MDS version at least 2.3.60"
14374
14375         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14376         touch $DIR/$tdir/spoo
14377         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14378         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14379                 error "cannot create/write a volatile file"
14380         [ "$FILESET" == "" ] &&
14381         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14382                 error "FID is still valid after close"
14383
14384         multiop_bg_pause $DIR/$tdir vVw4096_c
14385         local multi_pid=$!
14386
14387         local OLD_IFS=$IFS
14388         IFS=":"
14389         local fidv=($fid)
14390         IFS=$OLD_IFS
14391         # assume that the next FID for this client is sequential, since stdout
14392         # is unfortunately eaten by multiop_bg_pause
14393         local n=$((${fidv[1]} + 1))
14394         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14395         if [ "$FILESET" == "" ]; then
14396                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14397                         error "FID is missing before close"
14398         fi
14399         kill -USR1 $multi_pid
14400         # 1 second delay, so if mtime change we will see it
14401         sleep 1
14402         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14403         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14404 }
14405 run_test 185 "Volatile file support"
14406
14407 test_187a() {
14408         remote_mds_nodsh && skip "remote MDS with nodsh"
14409         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14410                 skip "Need MDS version at least 2.3.0"
14411
14412         local dir0=$DIR/$tdir/$testnum
14413         mkdir -p $dir0 || error "creating dir $dir0"
14414
14415         local file=$dir0/file1
14416         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14417         local dv1=$($LFS data_version $file)
14418         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14419         local dv2=$($LFS data_version $file)
14420         [[ $dv1 != $dv2 ]] ||
14421                 error "data version did not change on write $dv1 == $dv2"
14422
14423         # clean up
14424         rm -f $file1
14425 }
14426 run_test 187a "Test data version change"
14427
14428 test_187b() {
14429         remote_mds_nodsh && skip "remote MDS with nodsh"
14430         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14431                 skip "Need MDS version at least 2.3.0"
14432
14433         local dir0=$DIR/$tdir/$testnum
14434         mkdir -p $dir0 || error "creating dir $dir0"
14435
14436         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14437         [[ ${DV[0]} != ${DV[1]} ]] ||
14438                 error "data version did not change on write"\
14439                       " ${DV[0]} == ${DV[1]}"
14440
14441         # clean up
14442         rm -f $file1
14443 }
14444 run_test 187b "Test data version change on volatile file"
14445
14446 test_200() {
14447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14448         remote_mgs_nodsh && skip "remote MGS with nodsh"
14449         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14450
14451         local POOL=${POOL:-cea1}
14452         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14453         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14454         # Pool OST targets
14455         local first_ost=0
14456         local last_ost=$(($OSTCOUNT - 1))
14457         local ost_step=2
14458         local ost_list=$(seq $first_ost $ost_step $last_ost)
14459         local ost_range="$first_ost $last_ost $ost_step"
14460         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14461         local file_dir=$POOL_ROOT/file_tst
14462         local subdir=$test_path/subdir
14463         local rc=0
14464
14465         if ! combined_mgs_mds ; then
14466                 mount_mgs_client
14467         fi
14468
14469         while : ; do
14470                 # former test_200a test_200b
14471                 pool_add $POOL                          || { rc=$? ; break; }
14472                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14473                 # former test_200c test_200d
14474                 mkdir -p $test_path
14475                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14476                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14477                 mkdir -p $subdir
14478                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14479                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14480                                                         || { rc=$? ; break; }
14481                 # former test_200e test_200f
14482                 local files=$((OSTCOUNT*3))
14483                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14484                                                         || { rc=$? ; break; }
14485                 pool_create_files $POOL $file_dir $files "$ost_list" \
14486                                                         || { rc=$? ; break; }
14487                 # former test_200g test_200h
14488                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14489                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14490
14491                 # former test_201a test_201b test_201c
14492                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14493
14494                 local f=$test_path/$tfile
14495                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14496                 pool_remove $POOL $f                    || { rc=$? ; break; }
14497                 break
14498         done
14499
14500         destroy_test_pools
14501
14502         if ! combined_mgs_mds ; then
14503                 umount_mgs_client
14504         fi
14505         return $rc
14506 }
14507 run_test 200 "OST pools"
14508
14509 # usage: default_attr <count | size | offset>
14510 default_attr() {
14511         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14512 }
14513
14514 # usage: check_default_stripe_attr
14515 check_default_stripe_attr() {
14516         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14517         case $1 in
14518         --stripe-count|-c)
14519                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14520         --stripe-size|-S)
14521                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14522         --stripe-index|-i)
14523                 EXPECTED=-1;;
14524         *)
14525                 error "unknown getstripe attr '$1'"
14526         esac
14527
14528         [ $ACTUAL == $EXPECTED ] ||
14529                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14530 }
14531
14532 test_204a() {
14533         test_mkdir $DIR/$tdir
14534         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14535
14536         check_default_stripe_attr --stripe-count
14537         check_default_stripe_attr --stripe-size
14538         check_default_stripe_attr --stripe-index
14539 }
14540 run_test 204a "Print default stripe attributes"
14541
14542 test_204b() {
14543         test_mkdir $DIR/$tdir
14544         $LFS setstripe --stripe-count 1 $DIR/$tdir
14545
14546         check_default_stripe_attr --stripe-size
14547         check_default_stripe_attr --stripe-index
14548 }
14549 run_test 204b "Print default stripe size and offset"
14550
14551 test_204c() {
14552         test_mkdir $DIR/$tdir
14553         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14554
14555         check_default_stripe_attr --stripe-count
14556         check_default_stripe_attr --stripe-index
14557 }
14558 run_test 204c "Print default stripe count and offset"
14559
14560 test_204d() {
14561         test_mkdir $DIR/$tdir
14562         $LFS setstripe --stripe-index 0 $DIR/$tdir
14563
14564         check_default_stripe_attr --stripe-count
14565         check_default_stripe_attr --stripe-size
14566 }
14567 run_test 204d "Print default stripe count and size"
14568
14569 test_204e() {
14570         test_mkdir $DIR/$tdir
14571         $LFS setstripe -d $DIR/$tdir
14572
14573         check_default_stripe_attr --stripe-count --raw
14574         check_default_stripe_attr --stripe-size --raw
14575         check_default_stripe_attr --stripe-index --raw
14576 }
14577 run_test 204e "Print raw stripe attributes"
14578
14579 test_204f() {
14580         test_mkdir $DIR/$tdir
14581         $LFS setstripe --stripe-count 1 $DIR/$tdir
14582
14583         check_default_stripe_attr --stripe-size --raw
14584         check_default_stripe_attr --stripe-index --raw
14585 }
14586 run_test 204f "Print raw stripe size and offset"
14587
14588 test_204g() {
14589         test_mkdir $DIR/$tdir
14590         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14591
14592         check_default_stripe_attr --stripe-count --raw
14593         check_default_stripe_attr --stripe-index --raw
14594 }
14595 run_test 204g "Print raw stripe count and offset"
14596
14597 test_204h() {
14598         test_mkdir $DIR/$tdir
14599         $LFS setstripe --stripe-index 0 $DIR/$tdir
14600
14601         check_default_stripe_attr --stripe-count --raw
14602         check_default_stripe_attr --stripe-size --raw
14603 }
14604 run_test 204h "Print raw stripe count and size"
14605
14606 # Figure out which job scheduler is being used, if any,
14607 # or use a fake one
14608 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14609         JOBENV=SLURM_JOB_ID
14610 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14611         JOBENV=LSB_JOBID
14612 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14613         JOBENV=PBS_JOBID
14614 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14615         JOBENV=LOADL_STEP_ID
14616 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14617         JOBENV=JOB_ID
14618 else
14619         $LCTL list_param jobid_name > /dev/null 2>&1
14620         if [ $? -eq 0 ]; then
14621                 JOBENV=nodelocal
14622         else
14623                 JOBENV=FAKE_JOBID
14624         fi
14625 fi
14626 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14627
14628 verify_jobstats() {
14629         local cmd=($1)
14630         shift
14631         local facets="$@"
14632
14633 # we don't really need to clear the stats for this test to work, since each
14634 # command has a unique jobid, but it makes debugging easier if needed.
14635 #       for facet in $facets; do
14636 #               local dev=$(convert_facet2label $facet)
14637 #               # clear old jobstats
14638 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14639 #       done
14640
14641         # use a new JobID for each test, or we might see an old one
14642         [ "$JOBENV" = "FAKE_JOBID" ] &&
14643                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14644
14645         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14646
14647         [ "$JOBENV" = "nodelocal" ] && {
14648                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14649                 $LCTL set_param jobid_name=$FAKE_JOBID
14650                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14651         }
14652
14653         log "Test: ${cmd[*]}"
14654         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14655
14656         if [ $JOBENV = "FAKE_JOBID" ]; then
14657                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14658         else
14659                 ${cmd[*]}
14660         fi
14661
14662         # all files are created on OST0000
14663         for facet in $facets; do
14664                 local stats="*.$(convert_facet2label $facet).job_stats"
14665
14666                 # strip out libtool wrappers for in-tree executables
14667                 if [ $(do_facet $facet lctl get_param $stats |
14668                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14669                         do_facet $facet lctl get_param $stats
14670                         error "No jobstats for $JOBVAL found on $facet::$stats"
14671                 fi
14672         done
14673 }
14674
14675 jobstats_set() {
14676         local new_jobenv=$1
14677
14678         set_persistent_param_and_check client "jobid_var" \
14679                 "$FSNAME.sys.jobid_var" $new_jobenv
14680 }
14681
14682 test_205() { # Job stats
14683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14684         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14685                 skip "Need MDS version with at least 2.7.1"
14686         remote_mgs_nodsh && skip "remote MGS with nodsh"
14687         remote_mds_nodsh && skip "remote MDS with nodsh"
14688         remote_ost_nodsh && skip "remote OST with nodsh"
14689         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14690                 skip "Server doesn't support jobstats"
14691         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14692
14693         local old_jobenv=$($LCTL get_param -n jobid_var)
14694         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14695
14696         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14697                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14698         else
14699                 stack_trap "do_facet mgs $PERM_CMD \
14700                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14701         fi
14702         changelog_register
14703
14704         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14705                                 mdt.*.job_cleanup_interval | head -n 1)
14706         local new_interval=5
14707         do_facet $SINGLEMDS \
14708                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14709         stack_trap "do_facet $SINGLEMDS \
14710                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14711         local start=$SECONDS
14712
14713         local cmd
14714         # mkdir
14715         cmd="mkdir $DIR/$tdir"
14716         verify_jobstats "$cmd" "$SINGLEMDS"
14717         # rmdir
14718         cmd="rmdir $DIR/$tdir"
14719         verify_jobstats "$cmd" "$SINGLEMDS"
14720         # mkdir on secondary MDT
14721         if [ $MDSCOUNT -gt 1 ]; then
14722                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14723                 verify_jobstats "$cmd" "mds2"
14724         fi
14725         # mknod
14726         cmd="mknod $DIR/$tfile c 1 3"
14727         verify_jobstats "$cmd" "$SINGLEMDS"
14728         # unlink
14729         cmd="rm -f $DIR/$tfile"
14730         verify_jobstats "$cmd" "$SINGLEMDS"
14731         # create all files on OST0000 so verify_jobstats can find OST stats
14732         # open & close
14733         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14734         verify_jobstats "$cmd" "$SINGLEMDS"
14735         # setattr
14736         cmd="touch $DIR/$tfile"
14737         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14738         # write
14739         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14740         verify_jobstats "$cmd" "ost1"
14741         # read
14742         cancel_lru_locks osc
14743         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14744         verify_jobstats "$cmd" "ost1"
14745         # truncate
14746         cmd="$TRUNCATE $DIR/$tfile 0"
14747         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14748         # rename
14749         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14750         verify_jobstats "$cmd" "$SINGLEMDS"
14751         # jobstats expiry - sleep until old stats should be expired
14752         local left=$((new_interval + 5 - (SECONDS - start)))
14753         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14754                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14755                         "0" $left
14756         cmd="mkdir $DIR/$tdir.expire"
14757         verify_jobstats "$cmd" "$SINGLEMDS"
14758         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14759             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14760
14761         # Ensure that jobid are present in changelog (if supported by MDS)
14762         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14763                 changelog_dump | tail -10
14764                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14765                 [ $jobids -eq 9 ] ||
14766                         error "Wrong changelog jobid count $jobids != 9"
14767
14768                 # LU-5862
14769                 JOBENV="disable"
14770                 jobstats_set $JOBENV
14771                 touch $DIR/$tfile
14772                 changelog_dump | grep $tfile
14773                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14774                 [ $jobids -eq 0 ] ||
14775                         error "Unexpected jobids when jobid_var=$JOBENV"
14776         fi
14777
14778         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14779         JOBENV="JOBCOMPLEX"
14780         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14781
14782         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14783 }
14784 run_test 205 "Verify job stats"
14785
14786 # LU-1480, LU-1773 and LU-1657
14787 test_206() {
14788         mkdir -p $DIR/$tdir
14789         $LFS setstripe -c -1 $DIR/$tdir
14790 #define OBD_FAIL_LOV_INIT 0x1403
14791         $LCTL set_param fail_loc=0xa0001403
14792         $LCTL set_param fail_val=1
14793         touch $DIR/$tdir/$tfile || true
14794 }
14795 run_test 206 "fail lov_init_raid0() doesn't lbug"
14796
14797 test_207a() {
14798         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14799         local fsz=`stat -c %s $DIR/$tfile`
14800         cancel_lru_locks mdc
14801
14802         # do not return layout in getattr intent
14803 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14804         $LCTL set_param fail_loc=0x170
14805         local sz=`stat -c %s $DIR/$tfile`
14806
14807         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
14808
14809         rm -rf $DIR/$tfile
14810 }
14811 run_test 207a "can refresh layout at glimpse"
14812
14813 test_207b() {
14814         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14815         local cksum=`md5sum $DIR/$tfile`
14816         local fsz=`stat -c %s $DIR/$tfile`
14817         cancel_lru_locks mdc
14818         cancel_lru_locks osc
14819
14820         # do not return layout in getattr intent
14821 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
14822         $LCTL set_param fail_loc=0x171
14823
14824         # it will refresh layout after the file is opened but before read issues
14825         echo checksum is "$cksum"
14826         echo "$cksum" |md5sum -c --quiet || error "file differs"
14827
14828         rm -rf $DIR/$tfile
14829 }
14830 run_test 207b "can refresh layout at open"
14831
14832 test_208() {
14833         # FIXME: in this test suite, only RD lease is used. This is okay
14834         # for now as only exclusive open is supported. After generic lease
14835         # is done, this test suite should be revised. - Jinshan
14836
14837         remote_mds_nodsh && skip "remote MDS with nodsh"
14838         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
14839                 skip "Need MDS version at least 2.4.52"
14840
14841         echo "==== test 1: verify get lease work"
14842         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
14843
14844         echo "==== test 2: verify lease can be broken by upcoming open"
14845         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14846         local PID=$!
14847         sleep 1
14848
14849         $MULTIOP $DIR/$tfile oO_RDONLY:c
14850         kill -USR1 $PID && wait $PID || error "break lease error"
14851
14852         echo "==== test 3: verify lease can't be granted if an open already exists"
14853         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
14854         local PID=$!
14855         sleep 1
14856
14857         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
14858         kill -USR1 $PID && wait $PID || error "open file error"
14859
14860         echo "==== test 4: lease can sustain over recovery"
14861         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
14862         PID=$!
14863         sleep 1
14864
14865         fail mds1
14866
14867         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
14868
14869         echo "==== test 5: lease broken can't be regained by replay"
14870         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
14871         PID=$!
14872         sleep 1
14873
14874         # open file to break lease and then recovery
14875         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
14876         fail mds1
14877
14878         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
14879
14880         rm -f $DIR/$tfile
14881 }
14882 run_test 208 "Exclusive open"
14883
14884 test_209() {
14885         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
14886                 skip_env "must have disp_stripe"
14887
14888         touch $DIR/$tfile
14889         sync; sleep 5; sync;
14890
14891         echo 3 > /proc/sys/vm/drop_caches
14892         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14893
14894         # open/close 500 times
14895         for i in $(seq 500); do
14896                 cat $DIR/$tfile
14897         done
14898
14899         echo 3 > /proc/sys/vm/drop_caches
14900         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
14901
14902         echo "before: $req_before, after: $req_after"
14903         [ $((req_after - req_before)) -ge 300 ] &&
14904                 error "open/close requests are not freed"
14905         return 0
14906 }
14907 run_test 209 "read-only open/close requests should be freed promptly"
14908
14909 test_212() {
14910         size=`date +%s`
14911         size=$((size % 8192 + 1))
14912         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
14913         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
14914         rm -f $DIR/f212 $DIR/f212.xyz
14915 }
14916 run_test 212 "Sendfile test ============================================"
14917
14918 test_213() {
14919         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
14920         cancel_lru_locks osc
14921         lctl set_param fail_loc=0x8000040f
14922         # generate a read lock
14923         cat $DIR/$tfile > /dev/null
14924         # write to the file, it will try to cancel the above read lock.
14925         cat /etc/hosts >> $DIR/$tfile
14926 }
14927 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
14928
14929 test_214() { # for bug 20133
14930         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
14931         for (( i=0; i < 340; i++ )) ; do
14932                 touch $DIR/$tdir/d214c/a$i
14933         done
14934
14935         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
14936         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
14937         ls $DIR/d214c || error "ls $DIR/d214c failed"
14938         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
14939         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
14940 }
14941 run_test 214 "hash-indexed directory test - bug 20133"
14942
14943 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
14944 create_lnet_proc_files() {
14945         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
14946 }
14947
14948 # counterpart of create_lnet_proc_files
14949 remove_lnet_proc_files() {
14950         rm -f $TMP/lnet_$1.sys
14951 }
14952
14953 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14954 # 3rd arg as regexp for body
14955 check_lnet_proc_stats() {
14956         local l=$(cat "$TMP/lnet_$1" |wc -l)
14957         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
14958
14959         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
14960 }
14961
14962 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
14963 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
14964 # optional and can be regexp for 2nd line (lnet.routes case)
14965 check_lnet_proc_entry() {
14966         local blp=2          # blp stands for 'position of 1st line of body'
14967         [ -z "$5" ] || blp=3 # lnet.routes case
14968
14969         local l=$(cat "$TMP/lnet_$1" |wc -l)
14970         # subtracting one from $blp because the body can be empty
14971         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
14972
14973         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
14974                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
14975
14976         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
14977                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
14978
14979         # bail out if any unexpected line happened
14980         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
14981         [ "$?" != 0 ] || error "$2 misformatted"
14982 }
14983
14984 test_215() { # for bugs 18102, 21079, 21517
14985         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14986
14987         local N='(0|[1-9][0-9]*)'       # non-negative numeric
14988         local P='[1-9][0-9]*'           # positive numeric
14989         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
14990         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
14991         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
14992         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
14993
14994         local L1 # regexp for 1st line
14995         local L2 # regexp for 2nd line (optional)
14996         local BR # regexp for the rest (body)
14997
14998         # lnet.stats should look as 11 space-separated non-negative numerics
14999         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15000         create_lnet_proc_files "stats"
15001         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15002         remove_lnet_proc_files "stats"
15003
15004         # lnet.routes should look like this:
15005         # Routing disabled/enabled
15006         # net hops priority state router
15007         # where net is a string like tcp0, hops > 0, priority >= 0,
15008         # state is up/down,
15009         # router is a string like 192.168.1.1@tcp2
15010         L1="^Routing (disabled|enabled)$"
15011         L2="^net +hops +priority +state +router$"
15012         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15013         create_lnet_proc_files "routes"
15014         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15015         remove_lnet_proc_files "routes"
15016
15017         # lnet.routers should look like this:
15018         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15019         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15020         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15021         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15022         L1="^ref +rtr_ref +alive +router$"
15023         BR="^$P +$P +(up|down) +$NID$"
15024         create_lnet_proc_files "routers"
15025         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15026         remove_lnet_proc_files "routers"
15027
15028         # lnet.peers should look like this:
15029         # nid refs state last max rtr min tx min queue
15030         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15031         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15032         # numeric (0 or >0 or <0), queue >= 0.
15033         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15034         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15035         create_lnet_proc_files "peers"
15036         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15037         remove_lnet_proc_files "peers"
15038
15039         # lnet.buffers  should look like this:
15040         # pages count credits min
15041         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15042         L1="^pages +count +credits +min$"
15043         BR="^ +$N +$N +$I +$I$"
15044         create_lnet_proc_files "buffers"
15045         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15046         remove_lnet_proc_files "buffers"
15047
15048         # lnet.nis should look like this:
15049         # nid status alive refs peer rtr max tx min
15050         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15051         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15052         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15053         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15054         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15055         create_lnet_proc_files "nis"
15056         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15057         remove_lnet_proc_files "nis"
15058
15059         # can we successfully write to lnet.stats?
15060         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15061 }
15062 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15063
15064 test_216() { # bug 20317
15065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15066         remote_ost_nodsh && skip "remote OST with nodsh"
15067
15068         local node
15069         local facets=$(get_facets OST)
15070         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15071
15072         save_lustre_params client "osc.*.contention_seconds" > $p
15073         save_lustre_params $facets \
15074                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15075         save_lustre_params $facets \
15076                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15077         save_lustre_params $facets \
15078                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15079         clear_stats osc.*.osc_stats
15080
15081         # agressive lockless i/o settings
15082         do_nodes $(comma_list $(osts_nodes)) \
15083                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15084                         ldlm.namespaces.filter-*.contended_locks=0 \
15085                         ldlm.namespaces.filter-*.contention_seconds=60"
15086         lctl set_param -n osc.*.contention_seconds=60
15087
15088         $DIRECTIO write $DIR/$tfile 0 10 4096
15089         $CHECKSTAT -s 40960 $DIR/$tfile
15090
15091         # disable lockless i/o
15092         do_nodes $(comma_list $(osts_nodes)) \
15093                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15094                         ldlm.namespaces.filter-*.contended_locks=32 \
15095                         ldlm.namespaces.filter-*.contention_seconds=0"
15096         lctl set_param -n osc.*.contention_seconds=0
15097         clear_stats osc.*.osc_stats
15098
15099         dd if=/dev/zero of=$DIR/$tfile count=0
15100         $CHECKSTAT -s 0 $DIR/$tfile
15101
15102         restore_lustre_params <$p
15103         rm -f $p
15104         rm $DIR/$tfile
15105 }
15106 run_test 216 "check lockless direct write updates file size and kms correctly"
15107
15108 test_217() { # bug 22430
15109         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15110
15111         local node
15112         local nid
15113
15114         for node in $(nodes_list); do
15115                 nid=$(host_nids_address $node $NETTYPE)
15116                 if [[ $nid = *-* ]] ; then
15117                         echo "lctl ping $(h2nettype $nid)"
15118                         lctl ping $(h2nettype $nid)
15119                 else
15120                         echo "skipping $node (no hyphen detected)"
15121                 fi
15122         done
15123 }
15124 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15125
15126 test_218() {
15127        # do directio so as not to populate the page cache
15128        log "creating a 10 Mb file"
15129        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15130        log "starting reads"
15131        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15132        log "truncating the file"
15133        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15134        log "killing dd"
15135        kill %+ || true # reads might have finished
15136        echo "wait until dd is finished"
15137        wait
15138        log "removing the temporary file"
15139        rm -rf $DIR/$tfile || error "tmp file removal failed"
15140 }
15141 run_test 218 "parallel read and truncate should not deadlock"
15142
15143 test_219() {
15144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15145
15146         # write one partial page
15147         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15148         # set no grant so vvp_io_commit_write will do sync write
15149         $LCTL set_param fail_loc=0x411
15150         # write a full page at the end of file
15151         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15152
15153         $LCTL set_param fail_loc=0
15154         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15155         $LCTL set_param fail_loc=0x411
15156         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15157
15158         # LU-4201
15159         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15160         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15161 }
15162 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15163
15164 test_220() { #LU-325
15165         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15166         remote_ost_nodsh && skip "remote OST with nodsh"
15167         remote_mds_nodsh && skip "remote MDS with nodsh"
15168         remote_mgs_nodsh && skip "remote MGS with nodsh"
15169
15170         local OSTIDX=0
15171
15172         # create on MDT0000 so the last_id and next_id are correct
15173         mkdir $DIR/$tdir
15174         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15175         OST=${OST%_UUID}
15176
15177         # on the mdt's osc
15178         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15179         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15180                         osp.$mdtosc_proc1.prealloc_last_id)
15181         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15182                         osp.$mdtosc_proc1.prealloc_next_id)
15183
15184         $LFS df -i
15185
15186         if ! combined_mgs_mds ; then
15187                 mount_mgs_client
15188         fi
15189
15190         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15191         #define OBD_FAIL_OST_ENOINO              0x229
15192         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15193         create_pool $FSNAME.$TESTNAME || return 1
15194         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15195
15196         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15197
15198         MDSOBJS=$((last_id - next_id))
15199         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15200
15201         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15202         echo "OST still has $count kbytes free"
15203
15204         echo "create $MDSOBJS files @next_id..."
15205         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15206
15207         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15208                         osp.$mdtosc_proc1.prealloc_last_id)
15209         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15210                         osp.$mdtosc_proc1.prealloc_next_id)
15211
15212         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15213         $LFS df -i
15214
15215         echo "cleanup..."
15216
15217         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15218         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15219
15220         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15221                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15222         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15223                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15224         echo "unlink $MDSOBJS files @$next_id..."
15225         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15226
15227         if ! combined_mgs_mds ; then
15228                 umount_mgs_client
15229         fi
15230 }
15231 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15232
15233 test_221() {
15234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15235
15236         dd if=`which date` of=$MOUNT/date oflag=sync
15237         chmod +x $MOUNT/date
15238
15239         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15240         $LCTL set_param fail_loc=0x80001401
15241
15242         $MOUNT/date > /dev/null
15243         rm -f $MOUNT/date
15244 }
15245 run_test 221 "make sure fault and truncate race to not cause OOM"
15246
15247 test_222a () {
15248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15249
15250         rm -rf $DIR/$tdir
15251         test_mkdir $DIR/$tdir
15252         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15253         createmany -o $DIR/$tdir/$tfile 10
15254         cancel_lru_locks mdc
15255         cancel_lru_locks osc
15256         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15257         $LCTL set_param fail_loc=0x31a
15258         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15259         $LCTL set_param fail_loc=0
15260         rm -r $DIR/$tdir
15261 }
15262 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15263
15264 test_222b () {
15265         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15266
15267         rm -rf $DIR/$tdir
15268         test_mkdir $DIR/$tdir
15269         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15270         createmany -o $DIR/$tdir/$tfile 10
15271         cancel_lru_locks mdc
15272         cancel_lru_locks osc
15273         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15274         $LCTL set_param fail_loc=0x31a
15275         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15276         $LCTL set_param fail_loc=0
15277 }
15278 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15279
15280 test_223 () {
15281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15282
15283         rm -rf $DIR/$tdir
15284         test_mkdir $DIR/$tdir
15285         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15286         createmany -o $DIR/$tdir/$tfile 10
15287         cancel_lru_locks mdc
15288         cancel_lru_locks osc
15289         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15290         $LCTL set_param fail_loc=0x31b
15291         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15292         $LCTL set_param fail_loc=0
15293         rm -r $DIR/$tdir
15294 }
15295 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15296
15297 test_224a() { # LU-1039, MRP-303
15298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15299
15300         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15301         $LCTL set_param fail_loc=0x508
15302         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15303         $LCTL set_param fail_loc=0
15304         df $DIR
15305 }
15306 run_test 224a "Don't panic on bulk IO failure"
15307
15308 test_224b() { # LU-1039, MRP-303
15309         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15310
15311         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15312         cancel_lru_locks osc
15313         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15314         $LCTL set_param fail_loc=0x515
15315         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15316         $LCTL set_param fail_loc=0
15317         df $DIR
15318 }
15319 run_test 224b "Don't panic on bulk IO failure"
15320
15321 test_224c() { # LU-6441
15322         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15323         remote_mds_nodsh && skip "remote MDS with nodsh"
15324
15325         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15326         save_writethrough $p
15327         set_cache writethrough on
15328
15329         local pages_per_rpc=$($LCTL get_param \
15330                                 osc.*.max_pages_per_rpc)
15331         local at_max=$($LCTL get_param -n at_max)
15332         local timeout=$($LCTL get_param -n timeout)
15333         local test_at="at_max"
15334         local param_at="$FSNAME.sys.at_max"
15335         local test_timeout="timeout"
15336         local param_timeout="$FSNAME.sys.timeout"
15337
15338         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15339
15340         set_persistent_param_and_check client "$test_at" "$param_at" 0
15341         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15342
15343         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15344         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15345         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15346         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15347         sync
15348         do_facet ost1 "$LCTL set_param fail_loc=0"
15349
15350         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15351         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15352                 $timeout
15353
15354         $LCTL set_param -n $pages_per_rpc
15355         restore_lustre_params < $p
15356         rm -f $p
15357 }
15358 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15359
15360 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15361 test_225a () {
15362         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15363         if [ -z ${MDSSURVEY} ]; then
15364                 skip_env "mds-survey not found"
15365         fi
15366         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15367                 skip "Need MDS version at least 2.2.51"
15368
15369         local mds=$(facet_host $SINGLEMDS)
15370         local target=$(do_nodes $mds 'lctl dl' |
15371                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15372
15373         local cmd1="file_count=1000 thrhi=4"
15374         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15375         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15376         local cmd="$cmd1 $cmd2 $cmd3"
15377
15378         rm -f ${TMP}/mds_survey*
15379         echo + $cmd
15380         eval $cmd || error "mds-survey with zero-stripe failed"
15381         cat ${TMP}/mds_survey*
15382         rm -f ${TMP}/mds_survey*
15383 }
15384 run_test 225a "Metadata survey sanity with zero-stripe"
15385
15386 test_225b () {
15387         if [ -z ${MDSSURVEY} ]; then
15388                 skip_env "mds-survey not found"
15389         fi
15390         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15391                 skip "Need MDS version at least 2.2.51"
15392         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15393         remote_mds_nodsh && skip "remote MDS with nodsh"
15394         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15395                 skip_env "Need to mount OST to test"
15396         fi
15397
15398         local mds=$(facet_host $SINGLEMDS)
15399         local target=$(do_nodes $mds 'lctl dl' |
15400                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15401
15402         local cmd1="file_count=1000 thrhi=4"
15403         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15404         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15405         local cmd="$cmd1 $cmd2 $cmd3"
15406
15407         rm -f ${TMP}/mds_survey*
15408         echo + $cmd
15409         eval $cmd || error "mds-survey with stripe_count failed"
15410         cat ${TMP}/mds_survey*
15411         rm -f ${TMP}/mds_survey*
15412 }
15413 run_test 225b "Metadata survey sanity with stripe_count = 1"
15414
15415 mcreate_path2fid () {
15416         local mode=$1
15417         local major=$2
15418         local minor=$3
15419         local name=$4
15420         local desc=$5
15421         local path=$DIR/$tdir/$name
15422         local fid
15423         local rc
15424         local fid_path
15425
15426         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15427                 error "cannot create $desc"
15428
15429         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15430         rc=$?
15431         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15432
15433         fid_path=$($LFS fid2path $MOUNT $fid)
15434         rc=$?
15435         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15436
15437         [ "$path" == "$fid_path" ] ||
15438                 error "fid2path returned $fid_path, expected $path"
15439
15440         echo "pass with $path and $fid"
15441 }
15442
15443 test_226a () {
15444         rm -rf $DIR/$tdir
15445         mkdir -p $DIR/$tdir
15446
15447         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15448         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15449         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15450         mcreate_path2fid 0040666 0 0 dir "directory"
15451         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15452         mcreate_path2fid 0100666 0 0 file "regular file"
15453         mcreate_path2fid 0120666 0 0 link "symbolic link"
15454         mcreate_path2fid 0140666 0 0 sock "socket"
15455 }
15456 run_test 226a "call path2fid and fid2path on files of all type"
15457
15458 test_226b () {
15459         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15460
15461         local MDTIDX=1
15462
15463         rm -rf $DIR/$tdir
15464         mkdir -p $DIR/$tdir
15465         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15466                 error "create remote directory failed"
15467         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15468         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15469                                 "character special file (null)"
15470         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15471                                 "character special file (no device)"
15472         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15473         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15474                                 "block special file (loop)"
15475         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15476         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15477         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15478 }
15479 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15480
15481 # LU-1299 Executing or running ldd on a truncated executable does not
15482 # cause an out-of-memory condition.
15483 test_227() {
15484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15485         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15486
15487         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15488         chmod +x $MOUNT/date
15489
15490         $MOUNT/date > /dev/null
15491         ldd $MOUNT/date > /dev/null
15492         rm -f $MOUNT/date
15493 }
15494 run_test 227 "running truncated executable does not cause OOM"
15495
15496 # LU-1512 try to reuse idle OI blocks
15497 test_228a() {
15498         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15499         remote_mds_nodsh && skip "remote MDS with nodsh"
15500         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15501
15502         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15503         local myDIR=$DIR/$tdir
15504
15505         mkdir -p $myDIR
15506         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15507         $LCTL set_param fail_loc=0x80001002
15508         createmany -o $myDIR/t- 10000
15509         $LCTL set_param fail_loc=0
15510         # The guard is current the largest FID holder
15511         touch $myDIR/guard
15512         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15513                     tr -d '[')
15514         local IDX=$(($SEQ % 64))
15515
15516         do_facet $SINGLEMDS sync
15517         # Make sure journal flushed.
15518         sleep 6
15519         local blk1=$(do_facet $SINGLEMDS \
15520                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15521                      grep Blockcount | awk '{print $4}')
15522
15523         # Remove old files, some OI blocks will become idle.
15524         unlinkmany $myDIR/t- 10000
15525         # Create new files, idle OI blocks should be reused.
15526         createmany -o $myDIR/t- 2000
15527         do_facet $SINGLEMDS sync
15528         # Make sure journal flushed.
15529         sleep 6
15530         local blk2=$(do_facet $SINGLEMDS \
15531                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15532                      grep Blockcount | awk '{print $4}')
15533
15534         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15535 }
15536 run_test 228a "try to reuse idle OI blocks"
15537
15538 test_228b() {
15539         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15540         remote_mds_nodsh && skip "remote MDS with nodsh"
15541         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15542
15543         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15544         local myDIR=$DIR/$tdir
15545
15546         mkdir -p $myDIR
15547         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15548         $LCTL set_param fail_loc=0x80001002
15549         createmany -o $myDIR/t- 10000
15550         $LCTL set_param fail_loc=0
15551         # The guard is current the largest FID holder
15552         touch $myDIR/guard
15553         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15554                     tr -d '[')
15555         local IDX=$(($SEQ % 64))
15556
15557         do_facet $SINGLEMDS sync
15558         # Make sure journal flushed.
15559         sleep 6
15560         local blk1=$(do_facet $SINGLEMDS \
15561                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15562                      grep Blockcount | awk '{print $4}')
15563
15564         # Remove old files, some OI blocks will become idle.
15565         unlinkmany $myDIR/t- 10000
15566
15567         # stop the MDT
15568         stop $SINGLEMDS || error "Fail to stop MDT."
15569         # remount the MDT
15570         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15571
15572         df $MOUNT || error "Fail to df."
15573         # Create new files, idle OI blocks should be reused.
15574         createmany -o $myDIR/t- 2000
15575         do_facet $SINGLEMDS sync
15576         # Make sure journal flushed.
15577         sleep 6
15578         local blk2=$(do_facet $SINGLEMDS \
15579                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15580                      grep Blockcount | awk '{print $4}')
15581
15582         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15583 }
15584 run_test 228b "idle OI blocks can be reused after MDT restart"
15585
15586 #LU-1881
15587 test_228c() {
15588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15589         remote_mds_nodsh && skip "remote MDS with nodsh"
15590         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15591
15592         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15593         local myDIR=$DIR/$tdir
15594
15595         mkdir -p $myDIR
15596         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15597         $LCTL set_param fail_loc=0x80001002
15598         # 20000 files can guarantee there are index nodes in the OI file
15599         createmany -o $myDIR/t- 20000
15600         $LCTL set_param fail_loc=0
15601         # The guard is current the largest FID holder
15602         touch $myDIR/guard
15603         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15604                     tr -d '[')
15605         local IDX=$(($SEQ % 64))
15606
15607         do_facet $SINGLEMDS sync
15608         # Make sure journal flushed.
15609         sleep 6
15610         local blk1=$(do_facet $SINGLEMDS \
15611                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15612                      grep Blockcount | awk '{print $4}')
15613
15614         # Remove old files, some OI blocks will become idle.
15615         unlinkmany $myDIR/t- 20000
15616         rm -f $myDIR/guard
15617         # The OI file should become empty now
15618
15619         # Create new files, idle OI blocks should be reused.
15620         createmany -o $myDIR/t- 2000
15621         do_facet $SINGLEMDS sync
15622         # Make sure journal flushed.
15623         sleep 6
15624         local blk2=$(do_facet $SINGLEMDS \
15625                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15626                      grep Blockcount | awk '{print $4}')
15627
15628         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15629 }
15630 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15631
15632 test_229() { # LU-2482, LU-3448
15633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15634         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15635         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15636                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15637
15638         rm -f $DIR/$tfile
15639
15640         # Create a file with a released layout and stripe count 2.
15641         $MULTIOP $DIR/$tfile H2c ||
15642                 error "failed to create file with released layout"
15643
15644         $LFS getstripe -v $DIR/$tfile
15645
15646         local pattern=$($LFS getstripe -L $DIR/$tfile)
15647         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15648
15649         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15650                 error "getstripe"
15651         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15652         stat $DIR/$tfile || error "failed to stat released file"
15653
15654         chown $RUNAS_ID $DIR/$tfile ||
15655                 error "chown $RUNAS_ID $DIR/$tfile failed"
15656
15657         chgrp $RUNAS_ID $DIR/$tfile ||
15658                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15659
15660         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15661         rm $DIR/$tfile || error "failed to remove released file"
15662 }
15663 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15664
15665 test_230a() {
15666         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15667         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15668         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15669                 skip "Need MDS version at least 2.11.52"
15670
15671         local MDTIDX=1
15672
15673         test_mkdir $DIR/$tdir
15674         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15675         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15676         [ $mdt_idx -ne 0 ] &&
15677                 error "create local directory on wrong MDT $mdt_idx"
15678
15679         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15680                         error "create remote directory failed"
15681         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15682         [ $mdt_idx -ne $MDTIDX ] &&
15683                 error "create remote directory on wrong MDT $mdt_idx"
15684
15685         createmany -o $DIR/$tdir/test_230/t- 10 ||
15686                 error "create files on remote directory failed"
15687         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15688         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15689         rm -r $DIR/$tdir || error "unlink remote directory failed"
15690 }
15691 run_test 230a "Create remote directory and files under the remote directory"
15692
15693 test_230b() {
15694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15695         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15696         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15697                 skip "Need MDS version at least 2.11.52"
15698
15699         local MDTIDX=1
15700         local mdt_index
15701         local i
15702         local file
15703         local pid
15704         local stripe_count
15705         local migrate_dir=$DIR/$tdir/migrate_dir
15706         local other_dir=$DIR/$tdir/other_dir
15707
15708         test_mkdir $DIR/$tdir
15709         test_mkdir -i0 -c1 $migrate_dir
15710         test_mkdir -i0 -c1 $other_dir
15711         for ((i=0; i<10; i++)); do
15712                 mkdir -p $migrate_dir/dir_${i}
15713                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15714                         error "create files under remote dir failed $i"
15715         done
15716
15717         cp /etc/passwd $migrate_dir/$tfile
15718         cp /etc/passwd $other_dir/$tfile
15719         chattr +SAD $migrate_dir
15720         chattr +SAD $migrate_dir/$tfile
15721
15722         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15723         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15724         local old_dir_mode=$(stat -c%f $migrate_dir)
15725         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15726
15727         mkdir -p $migrate_dir/dir_default_stripe2
15728         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15729         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15730
15731         mkdir -p $other_dir
15732         ln $migrate_dir/$tfile $other_dir/luna
15733         ln $migrate_dir/$tfile $migrate_dir/sofia
15734         ln $other_dir/$tfile $migrate_dir/david
15735         ln -s $migrate_dir/$tfile $other_dir/zachary
15736         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15737         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15738
15739         $LFS migrate -m $MDTIDX $migrate_dir ||
15740                 error "fails on migrating remote dir to MDT1"
15741
15742         echo "migratate to MDT1, then checking.."
15743         for ((i = 0; i < 10; i++)); do
15744                 for file in $(find $migrate_dir/dir_${i}); do
15745                         mdt_index=$($LFS getstripe -m $file)
15746                         [ $mdt_index == $MDTIDX ] ||
15747                                 error "$file is not on MDT${MDTIDX}"
15748                 done
15749         done
15750
15751         # the multiple link file should still in MDT0
15752         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15753         [ $mdt_index == 0 ] ||
15754                 error "$file is not on MDT${MDTIDX}"
15755
15756         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15757         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15758                 error " expect $old_dir_flag get $new_dir_flag"
15759
15760         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15761         [ "$old_file_flag" = "$new_file_flag" ] ||
15762                 error " expect $old_file_flag get $new_file_flag"
15763
15764         local new_dir_mode=$(stat -c%f $migrate_dir)
15765         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15766                 error "expect mode $old_dir_mode get $new_dir_mode"
15767
15768         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15769         [ "$old_file_mode" = "$new_file_mode" ] ||
15770                 error "expect mode $old_file_mode get $new_file_mode"
15771
15772         diff /etc/passwd $migrate_dir/$tfile ||
15773                 error "$tfile different after migration"
15774
15775         diff /etc/passwd $other_dir/luna ||
15776                 error "luna different after migration"
15777
15778         diff /etc/passwd $migrate_dir/sofia ||
15779                 error "sofia different after migration"
15780
15781         diff /etc/passwd $migrate_dir/david ||
15782                 error "david different after migration"
15783
15784         diff /etc/passwd $other_dir/zachary ||
15785                 error "zachary different after migration"
15786
15787         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15788                 error "${tfile}_ln different after migration"
15789
15790         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15791                 error "${tfile}_ln_other different after migration"
15792
15793         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15794         [ $stripe_count = 2 ] ||
15795                 error "dir strpe_count $d != 2 after migration."
15796
15797         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15798         [ $stripe_count = 2 ] ||
15799                 error "file strpe_count $d != 2 after migration."
15800
15801         #migrate back to MDT0
15802         MDTIDX=0
15803
15804         $LFS migrate -m $MDTIDX $migrate_dir ||
15805                 error "fails on migrating remote dir to MDT0"
15806
15807         echo "migrate back to MDT0, checking.."
15808         for file in $(find $migrate_dir); do
15809                 mdt_index=$($LFS getstripe -m $file)
15810                 [ $mdt_index == $MDTIDX ] ||
15811                         error "$file is not on MDT${MDTIDX}"
15812         done
15813
15814         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15815         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15816                 error " expect $old_dir_flag get $new_dir_flag"
15817
15818         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15819         [ "$old_file_flag" = "$new_file_flag" ] ||
15820                 error " expect $old_file_flag get $new_file_flag"
15821
15822         local new_dir_mode=$(stat -c%f $migrate_dir)
15823         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15824                 error "expect mode $old_dir_mode get $new_dir_mode"
15825
15826         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15827         [ "$old_file_mode" = "$new_file_mode" ] ||
15828                 error "expect mode $old_file_mode get $new_file_mode"
15829
15830         diff /etc/passwd ${migrate_dir}/$tfile ||
15831                 error "$tfile different after migration"
15832
15833         diff /etc/passwd ${other_dir}/luna ||
15834                 error "luna different after migration"
15835
15836         diff /etc/passwd ${migrate_dir}/sofia ||
15837                 error "sofia different after migration"
15838
15839         diff /etc/passwd ${other_dir}/zachary ||
15840                 error "zachary different after migration"
15841
15842         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15843                 error "${tfile}_ln different after migration"
15844
15845         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15846                 error "${tfile}_ln_other different after migration"
15847
15848         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
15849         [ $stripe_count = 2 ] ||
15850                 error "dir strpe_count $d != 2 after migration."
15851
15852         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
15853         [ $stripe_count = 2 ] ||
15854                 error "file strpe_count $d != 2 after migration."
15855
15856         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15857 }
15858 run_test 230b "migrate directory"
15859
15860 test_230c() {
15861         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15862         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15863         remote_mds_nodsh && skip "remote MDS with nodsh"
15864         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15865                 skip "Need MDS version at least 2.11.52"
15866
15867         local MDTIDX=1
15868         local total=3
15869         local mdt_index
15870         local file
15871         local migrate_dir=$DIR/$tdir/migrate_dir
15872
15873         #If migrating directory fails in the middle, all entries of
15874         #the directory is still accessiable.
15875         test_mkdir $DIR/$tdir
15876         test_mkdir -i0 -c1 $migrate_dir
15877         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
15878         stat $migrate_dir
15879         createmany -o $migrate_dir/f $total ||
15880                 error "create files under ${migrate_dir} failed"
15881
15882         # fail after migrating top dir, and this will fail only once, so the
15883         # first sub file migration will fail (currently f3), others succeed.
15884         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
15885         do_facet mds1 lctl set_param fail_loc=0x1801
15886         local t=$(ls $migrate_dir | wc -l)
15887         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
15888                 error "migrate should fail"
15889         local u=$(ls $migrate_dir | wc -l)
15890         [ "$u" == "$t" ] || error "$u != $t during migration"
15891
15892         # add new dir/file should succeed
15893         mkdir $migrate_dir/dir ||
15894                 error "mkdir failed under migrating directory"
15895         touch $migrate_dir/file ||
15896                 error "create file failed under migrating directory"
15897
15898         # add file with existing name should fail
15899         for file in $migrate_dir/f*; do
15900                 stat $file > /dev/null || error "stat $file failed"
15901                 $OPENFILE -f O_CREAT:O_EXCL $file &&
15902                         error "open(O_CREAT|O_EXCL) $file should fail"
15903                 $MULTIOP $file m && error "create $file should fail"
15904                 touch $DIR/$tdir/remote_dir/$tfile ||
15905                         error "touch $tfile failed"
15906                 ln $DIR/$tdir/remote_dir/$tfile $file &&
15907                         error "link $file should fail"
15908                 mdt_index=$($LFS getstripe -m $file)
15909                 if [ $mdt_index == 0 ]; then
15910                         # file failed to migrate is not allowed to rename to
15911                         mv $DIR/$tdir/remote_dir/$tfile $file &&
15912                                 error "rename to $file should fail"
15913                 else
15914                         mv $DIR/$tdir/remote_dir/$tfile $file ||
15915                                 error "rename to $file failed"
15916                 fi
15917                 echo hello >> $file || error "write $file failed"
15918         done
15919
15920         # resume migration with different options should fail
15921         $LFS migrate -m 0 $migrate_dir &&
15922                 error "migrate -m 0 $migrate_dir should fail"
15923
15924         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
15925                 error "migrate -c 2 $migrate_dir should fail"
15926
15927         # resume migration should succeed
15928         $LFS migrate -m $MDTIDX $migrate_dir ||
15929                 error "migrate $migrate_dir failed"
15930
15931         echo "Finish migration, then checking.."
15932         for file in $(find $migrate_dir); do
15933                 mdt_index=$($LFS getstripe -m $file)
15934                 [ $mdt_index == $MDTIDX ] ||
15935                         error "$file is not on MDT${MDTIDX}"
15936         done
15937
15938         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15939 }
15940 run_test 230c "check directory accessiblity if migration failed"
15941
15942 test_230d() {
15943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15944         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15945         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15946                 skip "Need MDS version at least 2.11.52"
15947         # LU-11235
15948         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
15949
15950         local migrate_dir=$DIR/$tdir/migrate_dir
15951         local old_index
15952         local new_index
15953         local old_count
15954         local new_count
15955         local new_hash
15956         local mdt_index
15957         local i
15958         local j
15959
15960         old_index=$((RANDOM % MDSCOUNT))
15961         old_count=$((MDSCOUNT - old_index))
15962         new_index=$((RANDOM % MDSCOUNT))
15963         new_count=$((MDSCOUNT - new_index))
15964         new_hash="all_char"
15965
15966         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
15967         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
15968
15969         test_mkdir $DIR/$tdir
15970         test_mkdir -i $old_index -c $old_count $migrate_dir
15971
15972         for ((i=0; i<100; i++)); do
15973                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
15974                 createmany -o $migrate_dir/dir_${i}/f 100 ||
15975                         error "create files under remote dir failed $i"
15976         done
15977
15978         echo -n "Migrate from MDT$old_index "
15979         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
15980         echo -n "to MDT$new_index"
15981         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
15982         echo
15983
15984         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
15985         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
15986                 error "migrate remote dir error"
15987
15988         echo "Finish migration, then checking.."
15989         for file in $(find $migrate_dir); do
15990                 mdt_index=$($LFS getstripe -m $file)
15991                 if [ $mdt_index -lt $new_index ] ||
15992                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
15993                         error "$file is on MDT$mdt_index"
15994                 fi
15995         done
15996
15997         rm -rf $DIR/$tdir || error "rm dir failed after migration"
15998 }
15999 run_test 230d "check migrate big directory"
16000
16001 test_230e() {
16002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16003         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16004         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16005                 skip "Need MDS version at least 2.11.52"
16006
16007         local i
16008         local j
16009         local a_fid
16010         local b_fid
16011
16012         mkdir -p $DIR/$tdir
16013         mkdir $DIR/$tdir/migrate_dir
16014         mkdir $DIR/$tdir/other_dir
16015         touch $DIR/$tdir/migrate_dir/a
16016         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16017         ls $DIR/$tdir/other_dir
16018
16019         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16020                 error "migrate dir fails"
16021
16022         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16023         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16024
16025         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16026         [ $mdt_index == 0 ] || error "a is not on MDT0"
16027
16028         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16029                 error "migrate dir fails"
16030
16031         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16032         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16033
16034         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16035         [ $mdt_index == 1 ] || error "a is not on MDT1"
16036
16037         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16038         [ $mdt_index == 1 ] || error "b is not on MDT1"
16039
16040         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16041         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16042
16043         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16044
16045         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16046 }
16047 run_test 230e "migrate mulitple local link files"
16048
16049 test_230f() {
16050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16051         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16052         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16053                 skip "Need MDS version at least 2.11.52"
16054
16055         local a_fid
16056         local ln_fid
16057
16058         mkdir -p $DIR/$tdir
16059         mkdir $DIR/$tdir/migrate_dir
16060         $LFS mkdir -i1 $DIR/$tdir/other_dir
16061         touch $DIR/$tdir/migrate_dir/a
16062         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16063         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16064         ls $DIR/$tdir/other_dir
16065
16066         # a should be migrated to MDT1, since no other links on MDT0
16067         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16068                 error "#1 migrate dir fails"
16069         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16070         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16071         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16072         [ $mdt_index == 1 ] || error "a is not on MDT1"
16073
16074         # a should stay on MDT1, because it is a mulitple link file
16075         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16076                 error "#2 migrate dir fails"
16077         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16078         [ $mdt_index == 1 ] || error "a is not on MDT1"
16079
16080         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16081                 error "#3 migrate dir fails"
16082
16083         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16084         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16085         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16086
16087         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16088         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16089
16090         # a should be migrated to MDT0, since no other links on MDT1
16091         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16092                 error "#4 migrate dir fails"
16093         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16094         [ $mdt_index == 0 ] || error "a is not on MDT0"
16095
16096         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16097 }
16098 run_test 230f "migrate mulitple remote link files"
16099
16100 test_230g() {
16101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16102         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16103         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16104                 skip "Need MDS version at least 2.11.52"
16105
16106         mkdir -p $DIR/$tdir/migrate_dir
16107
16108         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16109                 error "migrating dir to non-exist MDT succeeds"
16110         true
16111 }
16112 run_test 230g "migrate dir to non-exist MDT"
16113
16114 test_230h() {
16115         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16116         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16117         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16118                 skip "Need MDS version at least 2.11.52"
16119
16120         local mdt_index
16121
16122         mkdir -p $DIR/$tdir/migrate_dir
16123
16124         $LFS migrate -m1 $DIR &&
16125                 error "migrating mountpoint1 should fail"
16126
16127         $LFS migrate -m1 $DIR/$tdir/.. &&
16128                 error "migrating mountpoint2 should fail"
16129
16130         # same as mv
16131         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16132                 error "migrating $tdir/migrate_dir/.. should fail"
16133
16134         true
16135 }
16136 run_test 230h "migrate .. and root"
16137
16138 test_230i() {
16139         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16140         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16141         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16142                 skip "Need MDS version at least 2.11.52"
16143
16144         mkdir -p $DIR/$tdir/migrate_dir
16145
16146         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16147                 error "migration fails with a tailing slash"
16148
16149         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16150                 error "migration fails with two tailing slashes"
16151 }
16152 run_test 230i "lfs migrate -m tolerates trailing slashes"
16153
16154 test_230j() {
16155         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16156         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16157                 skip "Need MDS version at least 2.11.52"
16158
16159         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16160         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16161                 error "create $tfile failed"
16162         cat /etc/passwd > $DIR/$tdir/$tfile
16163
16164         $LFS migrate -m 1 $DIR/$tdir
16165
16166         cmp /etc/passwd $DIR/$tdir/$tfile ||
16167                 error "DoM file mismatch after migration"
16168 }
16169 run_test 230j "DoM file data not changed after dir migration"
16170
16171 test_230k() {
16172         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16173         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16174                 skip "Need MDS version at least 2.11.56"
16175
16176         local total=20
16177         local files_on_starting_mdt=0
16178
16179         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16180         $LFS getdirstripe $DIR/$tdir
16181         for i in $(seq $total); do
16182                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16183                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16184                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16185         done
16186
16187         echo "$files_on_starting_mdt files on MDT0"
16188
16189         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16190         $LFS getdirstripe $DIR/$tdir
16191
16192         files_on_starting_mdt=0
16193         for i in $(seq $total); do
16194                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16195                         error "file $tfile.$i mismatch after migration"
16196                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16197                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16198         done
16199
16200         echo "$files_on_starting_mdt files on MDT1 after migration"
16201         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16202
16203         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16204         $LFS getdirstripe $DIR/$tdir
16205
16206         files_on_starting_mdt=0
16207         for i in $(seq $total); do
16208                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16209                         error "file $tfile.$i mismatch after 2nd migration"
16210                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16211                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16212         done
16213
16214         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16215         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16216
16217         true
16218 }
16219 run_test 230k "file data not changed after dir migration"
16220
16221 test_230l() {
16222         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16223         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16224                 skip "Need MDS version at least 2.11.56"
16225
16226         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16227         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16228                 error "create files under remote dir failed $i"
16229         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16230 }
16231 run_test 230l "readdir between MDTs won't crash"
16232
16233 test_231a()
16234 {
16235         # For simplicity this test assumes that max_pages_per_rpc
16236         # is the same across all OSCs
16237         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16238         local bulk_size=$((max_pages * PAGE_SIZE))
16239         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16240                                        head -n 1)
16241
16242         mkdir -p $DIR/$tdir
16243         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16244                 error "failed to set stripe with -S ${brw_size}M option"
16245
16246         # clear the OSC stats
16247         $LCTL set_param osc.*.stats=0 &>/dev/null
16248         stop_writeback
16249
16250         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16251         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16252                 oflag=direct &>/dev/null || error "dd failed"
16253
16254         sync; sleep 1; sync # just to be safe
16255         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16256         if [ x$nrpcs != "x1" ]; then
16257                 $LCTL get_param osc.*.stats
16258                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16259         fi
16260
16261         start_writeback
16262         # Drop the OSC cache, otherwise we will read from it
16263         cancel_lru_locks osc
16264
16265         # clear the OSC stats
16266         $LCTL set_param osc.*.stats=0 &>/dev/null
16267
16268         # Client reads $bulk_size.
16269         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16270                 iflag=direct &>/dev/null || error "dd failed"
16271
16272         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16273         if [ x$nrpcs != "x1" ]; then
16274                 $LCTL get_param osc.*.stats
16275                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16276         fi
16277 }
16278 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16279
16280 test_231b() {
16281         mkdir -p $DIR/$tdir
16282         local i
16283         for i in {0..1023}; do
16284                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16285                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16286                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16287         done
16288         sync
16289 }
16290 run_test 231b "must not assert on fully utilized OST request buffer"
16291
16292 test_232a() {
16293         mkdir -p $DIR/$tdir
16294         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16295
16296         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16297         do_facet ost1 $LCTL set_param fail_loc=0x31c
16298
16299         # ignore dd failure
16300         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16301
16302         do_facet ost1 $LCTL set_param fail_loc=0
16303         umount_client $MOUNT || error "umount failed"
16304         mount_client $MOUNT || error "mount failed"
16305         stop ost1 || error "cannot stop ost1"
16306         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16307 }
16308 run_test 232a "failed lock should not block umount"
16309
16310 test_232b() {
16311         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16312                 skip "Need MDS version at least 2.10.58"
16313
16314         mkdir -p $DIR/$tdir
16315         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16316         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16317         sync
16318         cancel_lru_locks osc
16319
16320         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16321         do_facet ost1 $LCTL set_param fail_loc=0x31c
16322
16323         # ignore failure
16324         $LFS data_version $DIR/$tdir/$tfile || true
16325
16326         do_facet ost1 $LCTL set_param fail_loc=0
16327         umount_client $MOUNT || error "umount failed"
16328         mount_client $MOUNT || error "mount failed"
16329         stop ost1 || error "cannot stop ost1"
16330         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16331 }
16332 run_test 232b "failed data version lock should not block umount"
16333
16334 test_233a() {
16335         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16336                 skip "Need MDS version at least 2.3.64"
16337         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16338
16339         local fid=$($LFS path2fid $MOUNT)
16340
16341         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16342                 error "cannot access $MOUNT using its FID '$fid'"
16343 }
16344 run_test 233a "checking that OBF of the FS root succeeds"
16345
16346 test_233b() {
16347         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16348                 skip "Need MDS version at least 2.5.90"
16349         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16350
16351         local fid=$($LFS path2fid $MOUNT/.lustre)
16352
16353         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16354                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16355
16356         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16357         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16358                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16359 }
16360 run_test 233b "checking that OBF of the FS .lustre succeeds"
16361
16362 test_234() {
16363         local p="$TMP/sanityN-$TESTNAME.parameters"
16364         save_lustre_params client "llite.*.xattr_cache" > $p
16365         lctl set_param llite.*.xattr_cache 1 ||
16366                 skip_env "xattr cache is not supported"
16367
16368         mkdir -p $DIR/$tdir || error "mkdir failed"
16369         touch $DIR/$tdir/$tfile || error "touch failed"
16370         # OBD_FAIL_LLITE_XATTR_ENOMEM
16371         $LCTL set_param fail_loc=0x1405
16372         getfattr -n user.attr $DIR/$tdir/$tfile &&
16373                 error "getfattr should have failed with ENOMEM"
16374         $LCTL set_param fail_loc=0x0
16375         rm -rf $DIR/$tdir
16376
16377         restore_lustre_params < $p
16378         rm -f $p
16379 }
16380 run_test 234 "xattr cache should not crash on ENOMEM"
16381
16382 test_235() {
16383         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16384                 skip "Need MDS version at least 2.4.52"
16385
16386         flock_deadlock $DIR/$tfile
16387         local RC=$?
16388         case $RC in
16389                 0)
16390                 ;;
16391                 124) error "process hangs on a deadlock"
16392                 ;;
16393                 *) error "error executing flock_deadlock $DIR/$tfile"
16394                 ;;
16395         esac
16396 }
16397 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16398
16399 #LU-2935
16400 test_236() {
16401         check_swap_layouts_support
16402
16403         local ref1=/etc/passwd
16404         local ref2=/etc/group
16405         local file1=$DIR/$tdir/f1
16406         local file2=$DIR/$tdir/f2
16407
16408         test_mkdir -c1 $DIR/$tdir
16409         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16410         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16411         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16412         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16413         local fd=$(free_fd)
16414         local cmd="exec $fd<>$file2"
16415         eval $cmd
16416         rm $file2
16417         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16418                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16419         cmd="exec $fd>&-"
16420         eval $cmd
16421         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16422
16423         #cleanup
16424         rm -rf $DIR/$tdir
16425 }
16426 run_test 236 "Layout swap on open unlinked file"
16427
16428 # LU-4659 linkea consistency
16429 test_238() {
16430         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16431                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16432                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16433                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16434
16435         touch $DIR/$tfile
16436         ln $DIR/$tfile $DIR/$tfile.lnk
16437         touch $DIR/$tfile.new
16438         mv $DIR/$tfile.new $DIR/$tfile
16439         local fid1=$($LFS path2fid $DIR/$tfile)
16440         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16441         local path1=$($LFS fid2path $FSNAME "$fid1")
16442         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16443         local path2=$($LFS fid2path $FSNAME "$fid2")
16444         [ $tfile.lnk == $path2 ] ||
16445                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16446         rm -f $DIR/$tfile*
16447 }
16448 run_test 238 "Verify linkea consistency"
16449
16450 test_239A() { # was test_239
16451         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16452                 skip "Need MDS version at least 2.5.60"
16453
16454         local list=$(comma_list $(mdts_nodes))
16455
16456         mkdir -p $DIR/$tdir
16457         createmany -o $DIR/$tdir/f- 5000
16458         unlinkmany $DIR/$tdir/f- 5000
16459         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16460                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16461         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16462                         osp.*MDT*.sync_in_flight" | calc_sum)
16463         [ "$changes" -eq 0 ] || error "$changes not synced"
16464 }
16465 run_test 239A "osp_sync test"
16466
16467 test_239a() { #LU-5297
16468         remote_mds_nodsh && skip "remote MDS with nodsh"
16469
16470         touch $DIR/$tfile
16471         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16472         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16473         chgrp $RUNAS_GID $DIR/$tfile
16474         wait_delete_completed
16475 }
16476 run_test 239a "process invalid osp sync record correctly"
16477
16478 test_239b() { #LU-5297
16479         remote_mds_nodsh && skip "remote MDS with nodsh"
16480
16481         touch $DIR/$tfile1
16482         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16483         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16484         chgrp $RUNAS_GID $DIR/$tfile1
16485         wait_delete_completed
16486         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16487         touch $DIR/$tfile2
16488         chgrp $RUNAS_GID $DIR/$tfile2
16489         wait_delete_completed
16490 }
16491 run_test 239b "process osp sync record with ENOMEM error correctly"
16492
16493 test_240() {
16494         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16495         remote_mds_nodsh && skip "remote MDS with nodsh"
16496
16497         mkdir -p $DIR/$tdir
16498
16499         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16500                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16501         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16502                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16503
16504         umount_client $MOUNT || error "umount failed"
16505         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16506         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16507         mount_client $MOUNT || error "failed to mount client"
16508
16509         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16510         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16511 }
16512 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16513
16514 test_241_bio() {
16515         local count=$1
16516         local bsize=$2
16517
16518         for LOOP in $(seq $count); do
16519                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16520                 cancel_lru_locks $OSC || true
16521         done
16522 }
16523
16524 test_241_dio() {
16525         local count=$1
16526         local bsize=$2
16527
16528         for LOOP in $(seq $1); do
16529                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16530                         2>/dev/null
16531         done
16532 }
16533
16534 test_241a() { # was test_241
16535         local bsize=$PAGE_SIZE
16536
16537         (( bsize < 40960 )) && bsize=40960
16538         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16539         ls -la $DIR/$tfile
16540         cancel_lru_locks $OSC
16541         test_241_bio 1000 $bsize &
16542         PID=$!
16543         test_241_dio 1000 $bsize
16544         wait $PID
16545 }
16546 run_test 241a "bio vs dio"
16547
16548 test_241b() {
16549         local bsize=$PAGE_SIZE
16550
16551         (( bsize < 40960 )) && bsize=40960
16552         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16553         ls -la $DIR/$tfile
16554         test_241_dio 1000 $bsize &
16555         PID=$!
16556         test_241_dio 1000 $bsize
16557         wait $PID
16558 }
16559 run_test 241b "dio vs dio"
16560
16561 test_242() {
16562         remote_mds_nodsh && skip "remote MDS with nodsh"
16563
16564         mkdir -p $DIR/$tdir
16565         touch $DIR/$tdir/$tfile
16566
16567         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16568         do_facet mds1 lctl set_param fail_loc=0x105
16569         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16570
16571         do_facet mds1 lctl set_param fail_loc=0
16572         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16573 }
16574 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16575
16576 test_243()
16577 {
16578         test_mkdir $DIR/$tdir
16579         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16580 }
16581 run_test 243 "various group lock tests"
16582
16583 test_244()
16584 {
16585         test_mkdir $DIR/$tdir
16586         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16587         sendfile_grouplock $DIR/$tdir/$tfile || \
16588                 error "sendfile+grouplock failed"
16589         rm -rf $DIR/$tdir
16590 }
16591 run_test 244 "sendfile with group lock tests"
16592
16593 test_245() {
16594         local flagname="multi_mod_rpcs"
16595         local connect_data_name="max_mod_rpcs"
16596         local out
16597
16598         # check if multiple modify RPCs flag is set
16599         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16600                 grep "connect_flags:")
16601         echo "$out"
16602
16603         echo "$out" | grep -qw $flagname
16604         if [ $? -ne 0 ]; then
16605                 echo "connect flag $flagname is not set"
16606                 return
16607         fi
16608
16609         # check if multiple modify RPCs data is set
16610         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16611         echo "$out"
16612
16613         echo "$out" | grep -qw $connect_data_name ||
16614                 error "import should have connect data $connect_data_name"
16615 }
16616 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16617
16618 test_246() { # LU-7371
16619         remote_ost_nodsh && skip "remote OST with nodsh"
16620         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16621                 skip "Need OST version >= 2.7.62"
16622
16623         do_facet ost1 $LCTL set_param fail_val=4095
16624 #define OBD_FAIL_OST_READ_SIZE          0x234
16625         do_facet ost1 $LCTL set_param fail_loc=0x234
16626         $LFS setstripe $DIR/$tfile -i 0 -c 1
16627         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16628         cancel_lru_locks $FSNAME-OST0000
16629         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16630 }
16631 run_test 246 "Read file of size 4095 should return right length"
16632
16633 cleanup_247() {
16634         local submount=$1
16635
16636         trap 0
16637         umount_client $submount
16638         rmdir $submount
16639 }
16640
16641 test_247a() {
16642         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16643                 grep -q subtree ||
16644                 skip_env "Fileset feature is not supported"
16645
16646         local submount=${MOUNT}_$tdir
16647
16648         mkdir $MOUNT/$tdir
16649         mkdir -p $submount || error "mkdir $submount failed"
16650         FILESET="$FILESET/$tdir" mount_client $submount ||
16651                 error "mount $submount failed"
16652         trap "cleanup_247 $submount" EXIT
16653         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16654         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16655                 error "read $MOUNT/$tdir/$tfile failed"
16656         cleanup_247 $submount
16657 }
16658 run_test 247a "mount subdir as fileset"
16659
16660 test_247b() {
16661         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16662                 skip_env "Fileset feature is not supported"
16663
16664         local submount=${MOUNT}_$tdir
16665
16666         rm -rf $MOUNT/$tdir
16667         mkdir -p $submount || error "mkdir $submount failed"
16668         SKIP_FILESET=1
16669         FILESET="$FILESET/$tdir" mount_client $submount &&
16670                 error "mount $submount should fail"
16671         rmdir $submount
16672 }
16673 run_test 247b "mount subdir that dose not exist"
16674
16675 test_247c() {
16676         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16677                 skip_env "Fileset feature is not supported"
16678
16679         local submount=${MOUNT}_$tdir
16680
16681         mkdir -p $MOUNT/$tdir/dir1
16682         mkdir -p $submount || error "mkdir $submount failed"
16683         trap "cleanup_247 $submount" EXIT
16684         FILESET="$FILESET/$tdir" mount_client $submount ||
16685                 error "mount $submount failed"
16686         local fid=$($LFS path2fid $MOUNT/)
16687         $LFS fid2path $submount $fid && error "fid2path should fail"
16688         cleanup_247 $submount
16689 }
16690 run_test 247c "running fid2path outside root"
16691
16692 test_247d() {
16693         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16694                 skip "Fileset feature is not supported"
16695
16696         local submount=${MOUNT}_$tdir
16697
16698         mkdir -p $MOUNT/$tdir/dir1
16699         mkdir -p $submount || error "mkdir $submount failed"
16700         FILESET="$FILESET/$tdir" mount_client $submount ||
16701                 error "mount $submount failed"
16702         trap "cleanup_247 $submount" EXIT
16703         local fid=$($LFS path2fid $submount/dir1)
16704         $LFS fid2path $submount $fid || error "fid2path should succeed"
16705         cleanup_247 $submount
16706 }
16707 run_test 247d "running fid2path inside root"
16708
16709 # LU-8037
16710 test_247e() {
16711         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16712                 grep -q subtree ||
16713                 skip "Fileset feature is not supported"
16714
16715         local submount=${MOUNT}_$tdir
16716
16717         mkdir $MOUNT/$tdir
16718         mkdir -p $submount || error "mkdir $submount failed"
16719         FILESET="$FILESET/.." mount_client $submount &&
16720                 error "mount $submount should fail"
16721         rmdir $submount
16722 }
16723 run_test 247e "mount .. as fileset"
16724
16725 test_248() {
16726         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16727         [ -z "$fast_read_sav" ] && skip "no fast read support"
16728
16729         # create a large file for fast read verification
16730         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16731
16732         # make sure the file is created correctly
16733         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16734                 { rm -f $DIR/$tfile; skip "file creation error"; }
16735
16736         echo "Test 1: verify that fast read is 4 times faster on cache read"
16737
16738         # small read with fast read enabled
16739         $LCTL set_param -n llite.*.fast_read=1
16740         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16741                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16742                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16743         # small read with fast read disabled
16744         $LCTL set_param -n llite.*.fast_read=0
16745         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16746                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16747                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16748
16749         # verify that fast read is 4 times faster for cache read
16750         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16751                 error_not_in_vm "fast read was not 4 times faster: " \
16752                            "$t_fast vs $t_slow"
16753
16754         echo "Test 2: verify the performance between big and small read"
16755         $LCTL set_param -n llite.*.fast_read=1
16756
16757         # 1k non-cache read
16758         cancel_lru_locks osc
16759         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16760                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16761                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16762
16763         # 1M non-cache read
16764         cancel_lru_locks osc
16765         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16766                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16767                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16768
16769         # verify that big IO is not 4 times faster than small IO
16770         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16771                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16772
16773         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16774         rm -f $DIR/$tfile
16775 }
16776 run_test 248 "fast read verification"
16777
16778 test_249() { # LU-7890
16779         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16780                 skip "Need at least version 2.8.54"
16781
16782         rm -f $DIR/$tfile
16783         $LFS setstripe -c 1 $DIR/$tfile
16784         # Offset 2T == 4k * 512M
16785         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16786                 error "dd to 2T offset failed"
16787 }
16788 run_test 249 "Write above 2T file size"
16789
16790 test_250() {
16791         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16792          && skip "no 16TB file size limit on ZFS"
16793
16794         $LFS setstripe -c 1 $DIR/$tfile
16795         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16796         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16797         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16798         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16799                 conv=notrunc,fsync && error "append succeeded"
16800         return 0
16801 }
16802 run_test 250 "Write above 16T limit"
16803
16804 test_251() {
16805         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16806
16807         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
16808         #Skip once - writing the first stripe will succeed
16809         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16810         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
16811                 error "short write happened"
16812
16813         $LCTL set_param fail_loc=0xa0001407 fail_val=1
16814         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
16815                 error "short read happened"
16816
16817         rm -f $DIR/$tfile
16818 }
16819 run_test 251 "Handling short read and write correctly"
16820
16821 test_252() {
16822         remote_mds_nodsh && skip "remote MDS with nodsh"
16823         remote_ost_nodsh && skip "remote OST with nodsh"
16824         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
16825                 skip_env "ldiskfs only test"
16826         fi
16827
16828         local tgt
16829         local dev
16830         local out
16831         local uuid
16832         local num
16833         local gen
16834
16835         # check lr_reader on OST0000
16836         tgt=ost1
16837         dev=$(facet_device $tgt)
16838         out=$(do_facet $tgt $LR_READER $dev)
16839         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16840         echo "$out"
16841         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
16842         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
16843                 error "Invalid uuid returned by $LR_READER on target $tgt"
16844         echo -e "uuid returned by $LR_READER is '$uuid'\n"
16845
16846         # check lr_reader -c on MDT0000
16847         tgt=mds1
16848         dev=$(facet_device $tgt)
16849         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
16850                 skip "$LR_READER does not support additional options"
16851         fi
16852         out=$(do_facet $tgt $LR_READER -c $dev)
16853         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16854         echo "$out"
16855         num=$(echo "$out" | grep -c "mdtlov")
16856         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
16857                 error "Invalid number of mdtlov clients returned by $LR_READER"
16858         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
16859
16860         # check lr_reader -cr on MDT0000
16861         out=$(do_facet $tgt $LR_READER -cr $dev)
16862         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
16863         echo "$out"
16864         echo "$out" | grep -q "^reply_data:$" ||
16865                 error "$LR_READER should have returned 'reply_data' section"
16866         num=$(echo "$out" | grep -c "client_generation")
16867         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
16868 }
16869 run_test 252 "check lr_reader tool"
16870
16871 test_253() {
16872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16873         remote_mds_nodsh && skip "remote MDS with nodsh"
16874         remote_mgs_nodsh && skip "remote MGS with nodsh"
16875
16876         local ostidx=0
16877         local rc=0
16878         local ost_name=$(ostname_from_index $ostidx)
16879
16880         # on the mdt's osc
16881         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
16882         do_facet $SINGLEMDS $LCTL get_param -n \
16883                 osp.$mdtosc_proc1.reserved_mb_high ||
16884                 skip  "remote MDS does not support reserved_mb_high"
16885
16886         rm -rf $DIR/$tdir
16887         wait_mds_ost_sync
16888         wait_delete_completed
16889         mkdir $DIR/$tdir
16890
16891         if ! combined_mgs_mds ; then
16892                 mount_mgs_client
16893         fi
16894         pool_add $TESTNAME || error "Pool creation failed"
16895         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
16896
16897         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
16898                 error "Setstripe failed"
16899
16900         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
16901
16902         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
16903                     grep "watermarks")
16904         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
16905
16906         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16907                         osp.$mdtosc_proc1.prealloc_status)
16908         echo "prealloc_status $oa_status"
16909
16910         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
16911                 error "File creation should fail"
16912
16913         #object allocation was stopped, but we still able to append files
16914         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
16915                 oflag=append || error "Append failed"
16916
16917         rm -f $DIR/$tdir/$tfile.0
16918
16919         # For this test, we want to delete the files we created to go out of
16920         # space but leave the watermark, so we remain nearly out of space
16921         ost_watermarks_enospc_delete_files $tfile $ostidx
16922
16923         wait_delete_completed
16924
16925         sleep_maxage
16926
16927         for i in $(seq 10 12); do
16928                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
16929                         2>/dev/null || error "File creation failed after rm"
16930         done
16931
16932         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
16933                         osp.$mdtosc_proc1.prealloc_status)
16934         echo "prealloc_status $oa_status"
16935
16936         if (( oa_status != 0 )); then
16937                 error "Object allocation still disable after rm"
16938         fi
16939
16940         if ! combined_mgs_mds ; then
16941                 umount_mgs_client
16942         fi
16943 }
16944 run_test 253 "Check object allocation limit"
16945
16946 test_254() {
16947         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16948         remote_mds_nodsh && skip "remote MDS with nodsh"
16949         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
16950                 skip "MDS does not support changelog_size"
16951
16952         local cl_user
16953         local MDT0=$(facet_svc $SINGLEMDS)
16954
16955         changelog_register || error "changelog_register failed"
16956
16957         changelog_clear 0 || error "changelog_clear failed"
16958
16959         local size1=$(do_facet $SINGLEMDS \
16960                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16961         echo "Changelog size $size1"
16962
16963         rm -rf $DIR/$tdir
16964         $LFS mkdir -i 0 $DIR/$tdir
16965         # change something
16966         mkdir -p $DIR/$tdir/pics/2008/zachy
16967         touch $DIR/$tdir/pics/2008/zachy/timestamp
16968         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
16969         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
16970         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
16971         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
16972         rm $DIR/$tdir/pics/desktop.jpg
16973
16974         local size2=$(do_facet $SINGLEMDS \
16975                       $LCTL get_param -n mdd.$MDT0.changelog_size)
16976         echo "Changelog size after work $size2"
16977
16978         (( $size2 > $size1 )) ||
16979                 error "new Changelog size=$size2 less than old size=$size1"
16980 }
16981 run_test 254 "Check changelog size"
16982
16983 ladvise_no_type()
16984 {
16985         local type=$1
16986         local file=$2
16987
16988         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
16989                 awk -F: '{print $2}' | grep $type > /dev/null
16990         if [ $? -ne 0 ]; then
16991                 return 0
16992         fi
16993         return 1
16994 }
16995
16996 ladvise_no_ioctl()
16997 {
16998         local file=$1
16999
17000         lfs ladvise -a willread $file > /dev/null 2>&1
17001         if [ $? -eq 0 ]; then
17002                 return 1
17003         fi
17004
17005         lfs ladvise -a willread $file 2>&1 |
17006                 grep "Inappropriate ioctl for device" > /dev/null
17007         if [ $? -eq 0 ]; then
17008                 return 0
17009         fi
17010         return 1
17011 }
17012
17013 percent() {
17014         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17015 }
17016
17017 # run a random read IO workload
17018 # usage: random_read_iops <filename> <filesize> <iosize>
17019 random_read_iops() {
17020         local file=$1
17021         local fsize=$2
17022         local iosize=${3:-4096}
17023
17024         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17025                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17026 }
17027
17028 drop_file_oss_cache() {
17029         local file="$1"
17030         local nodes="$2"
17031
17032         $LFS ladvise -a dontneed $file 2>/dev/null ||
17033                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17034 }
17035
17036 ladvise_willread_performance()
17037 {
17038         local repeat=10
17039         local average_origin=0
17040         local average_cache=0
17041         local average_ladvise=0
17042
17043         for ((i = 1; i <= $repeat; i++)); do
17044                 echo "Iter $i/$repeat: reading without willread hint"
17045                 cancel_lru_locks osc
17046                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17047                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17048                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17049                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17050
17051                 cancel_lru_locks osc
17052                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17053                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17054                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17055
17056                 cancel_lru_locks osc
17057                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17058                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17059                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17060                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17061                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17062         done
17063         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17064         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17065         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17066
17067         speedup_cache=$(percent $average_cache $average_origin)
17068         speedup_ladvise=$(percent $average_ladvise $average_origin)
17069
17070         echo "Average uncached read: $average_origin"
17071         echo "Average speedup with OSS cached read: " \
17072                 "$average_cache = +$speedup_cache%"
17073         echo "Average speedup with ladvise willread: " \
17074                 "$average_ladvise = +$speedup_ladvise%"
17075
17076         local lowest_speedup=20
17077         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17078                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17079                         "got $average_cache%. Skipping ladvise willread check."
17080                 return 0
17081         fi
17082
17083         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17084         # it is still good to run until then to exercise 'ladvise willread'
17085         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17086                 [ "$ost1_FSTYPE" = "zfs" ] &&
17087                 echo "osd-zfs does not support dontneed or drop_caches" &&
17088                 return 0
17089
17090         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17091         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17092                 error_not_in_vm "Speedup with willread is less than " \
17093                         "$lowest_speedup%, got $average_ladvise%"
17094 }
17095
17096 test_255a() {
17097         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17098                 skip "lustre < 2.8.54 does not support ladvise "
17099         remote_ost_nodsh && skip "remote OST with nodsh"
17100
17101         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17102
17103         ladvise_no_type willread $DIR/$tfile &&
17104                 skip "willread ladvise is not supported"
17105
17106         ladvise_no_ioctl $DIR/$tfile &&
17107                 skip "ladvise ioctl is not supported"
17108
17109         local size_mb=100
17110         local size=$((size_mb * 1048576))
17111         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17112                 error "dd to $DIR/$tfile failed"
17113
17114         lfs ladvise -a willread $DIR/$tfile ||
17115                 error "Ladvise failed with no range argument"
17116
17117         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17118                 error "Ladvise failed with no -l or -e argument"
17119
17120         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17121                 error "Ladvise failed with only -e argument"
17122
17123         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17124                 error "Ladvise failed with only -l argument"
17125
17126         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17127                 error "End offset should not be smaller than start offset"
17128
17129         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17130                 error "End offset should not be equal to start offset"
17131
17132         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17133                 error "Ladvise failed with overflowing -s argument"
17134
17135         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17136                 error "Ladvise failed with overflowing -e argument"
17137
17138         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17139                 error "Ladvise failed with overflowing -l argument"
17140
17141         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17142                 error "Ladvise succeeded with conflicting -l and -e arguments"
17143
17144         echo "Synchronous ladvise should wait"
17145         local delay=4
17146 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17147         do_nodes $(comma_list $(osts_nodes)) \
17148                 $LCTL set_param fail_val=$delay fail_loc=0x237
17149
17150         local start_ts=$SECONDS
17151         lfs ladvise -a willread $DIR/$tfile ||
17152                 error "Ladvise failed with no range argument"
17153         local end_ts=$SECONDS
17154         local inteval_ts=$((end_ts - start_ts))
17155
17156         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17157                 error "Synchronous advice didn't wait reply"
17158         fi
17159
17160         echo "Asynchronous ladvise shouldn't wait"
17161         local start_ts=$SECONDS
17162         lfs ladvise -a willread -b $DIR/$tfile ||
17163                 error "Ladvise failed with no range argument"
17164         local end_ts=$SECONDS
17165         local inteval_ts=$((end_ts - start_ts))
17166
17167         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17168                 error "Asynchronous advice blocked"
17169         fi
17170
17171         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17172         ladvise_willread_performance
17173 }
17174 run_test 255a "check 'lfs ladvise -a willread'"
17175
17176 facet_meminfo() {
17177         local facet=$1
17178         local info=$2
17179
17180         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17181 }
17182
17183 test_255b() {
17184         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17185                 skip "lustre < 2.8.54 does not support ladvise "
17186         remote_ost_nodsh && skip "remote OST with nodsh"
17187
17188         lfs setstripe -c 1 -i 0 $DIR/$tfile
17189
17190         ladvise_no_type dontneed $DIR/$tfile &&
17191                 skip "dontneed ladvise is not supported"
17192
17193         ladvise_no_ioctl $DIR/$tfile &&
17194                 skip "ladvise ioctl is not supported"
17195
17196         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17197                 [ "$ost1_FSTYPE" = "zfs" ] &&
17198                 skip "zfs-osd does not support 'ladvise dontneed'"
17199
17200         local size_mb=100
17201         local size=$((size_mb * 1048576))
17202         # In order to prevent disturbance of other processes, only check 3/4
17203         # of the memory usage
17204         local kibibytes=$((size_mb * 1024 * 3 / 4))
17205
17206         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17207                 error "dd to $DIR/$tfile failed"
17208
17209         #force write to complete before dropping OST cache & checking memory
17210         sync
17211
17212         local total=$(facet_meminfo ost1 MemTotal)
17213         echo "Total memory: $total KiB"
17214
17215         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17216         local before_read=$(facet_meminfo ost1 Cached)
17217         echo "Cache used before read: $before_read KiB"
17218
17219         lfs ladvise -a willread $DIR/$tfile ||
17220                 error "Ladvise willread failed"
17221         local after_read=$(facet_meminfo ost1 Cached)
17222         echo "Cache used after read: $after_read KiB"
17223
17224         lfs ladvise -a dontneed $DIR/$tfile ||
17225                 error "Ladvise dontneed again failed"
17226         local no_read=$(facet_meminfo ost1 Cached)
17227         echo "Cache used after dontneed ladvise: $no_read KiB"
17228
17229         if [ $total -lt $((before_read + kibibytes)) ]; then
17230                 echo "Memory is too small, abort checking"
17231                 return 0
17232         fi
17233
17234         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17235                 error "Ladvise willread should use more memory" \
17236                         "than $kibibytes KiB"
17237         fi
17238
17239         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17240                 error "Ladvise dontneed should release more memory" \
17241                         "than $kibibytes KiB"
17242         fi
17243 }
17244 run_test 255b "check 'lfs ladvise -a dontneed'"
17245
17246 test_255c() {
17247         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17248                 skip "lustre < 2.10.53 does not support lockahead"
17249
17250         local count
17251         local new_count
17252         local difference
17253         local i
17254         local rc
17255
17256         test_mkdir -p $DIR/$tdir
17257         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17258
17259         #test 10 returns only success/failure
17260         i=10
17261         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17262         rc=$?
17263         if [ $rc -eq 255 ]; then
17264                 error "Ladvise test${i} failed, ${rc}"
17265         fi
17266
17267         #test 11 counts lock enqueue requests, all others count new locks
17268         i=11
17269         count=$(do_facet ost1 \
17270                 $LCTL get_param -n ost.OSS.ost.stats)
17271         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17272
17273         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17274         rc=$?
17275         if [ $rc -eq 255 ]; then
17276                 error "Ladvise test${i} failed, ${rc}"
17277         fi
17278
17279         new_count=$(do_facet ost1 \
17280                 $LCTL get_param -n ost.OSS.ost.stats)
17281         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17282                    awk '{ print $2 }')
17283
17284         difference="$((new_count - count))"
17285         if [ $difference -ne $rc ]; then
17286                 error "Ladvise test${i}, bad enqueue count, returned " \
17287                       "${rc}, actual ${difference}"
17288         fi
17289
17290         for i in $(seq 12 21); do
17291                 # If we do not do this, we run the risk of having too many
17292                 # locks and starting lock cancellation while we are checking
17293                 # lock counts.
17294                 cancel_lru_locks osc
17295
17296                 count=$($LCTL get_param -n \
17297                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17298
17299                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17300                 rc=$?
17301                 if [ $rc -eq 255 ]; then
17302                         error "Ladvise test ${i} failed, ${rc}"
17303                 fi
17304
17305                 new_count=$($LCTL get_param -n \
17306                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17307                 difference="$((new_count - count))"
17308
17309                 # Test 15 output is divided by 100 to map down to valid return
17310                 if [ $i -eq 15 ]; then
17311                         rc="$((rc * 100))"
17312                 fi
17313
17314                 if [ $difference -ne $rc ]; then
17315                         error "Ladvise test ${i}, bad lock count, returned " \
17316                               "${rc}, actual ${difference}"
17317                 fi
17318         done
17319
17320         #test 22 returns only success/failure
17321         i=22
17322         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17323         rc=$?
17324         if [ $rc -eq 255 ]; then
17325                 error "Ladvise test${i} failed, ${rc}"
17326         fi
17327 }
17328 run_test 255c "suite of ladvise lockahead tests"
17329
17330 test_256() {
17331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17332         remote_mds_nodsh && skip "remote MDS with nodsh"
17333         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17334         changelog_users $SINGLEMDS | grep "^cl" &&
17335                 skip "active changelog user"
17336
17337         local cl_user
17338         local cat_sl
17339         local mdt_dev
17340
17341         mdt_dev=$(mdsdevname 1)
17342         echo $mdt_dev
17343
17344         changelog_register || error "changelog_register failed"
17345
17346         rm -rf $DIR/$tdir
17347         mkdir -p $DIR/$tdir
17348
17349         changelog_clear 0 || error "changelog_clear failed"
17350
17351         # change something
17352         touch $DIR/$tdir/{1..10}
17353
17354         # stop the MDT
17355         stop $SINGLEMDS || error "Fail to stop MDT"
17356
17357         # remount the MDT
17358
17359         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17360
17361         #after mount new plainllog is used
17362         touch $DIR/$tdir/{11..19}
17363         local tmpfile=$(mktemp -u $tfile.XXXXXX)
17364         cat_sl=$(do_facet $SINGLEMDS "sync; \
17365                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17366                  llog_reader $tmpfile | grep -c type=1064553b")
17367         do_facet $SINGLEMDS llog_reader $tmpfile
17368
17369         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17370
17371         changelog_clear 0 || error "changelog_clear failed"
17372
17373         cat_sl=$(do_facet $SINGLEMDS "sync; \
17374                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17375                  llog_reader $tmpfile | grep -c type=1064553b; rm -f $tmpfile")
17376
17377         if (( cat_sl == 2 )); then
17378                 error "Empty plain llog was not deleted from changelog catalog"
17379         elif (( cat_sl != 1 )); then
17380                 error "Active plain llog shouldn't be deleted from catalog"
17381         fi
17382 }
17383 run_test 256 "Check llog delete for empty and not full state"
17384
17385 test_257() {
17386         remote_mds_nodsh && skip "remote MDS with nodsh"
17387         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17388                 skip "Need MDS version at least 2.8.55"
17389
17390         test_mkdir $DIR/$tdir
17391
17392         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17393                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17394         stat $DIR/$tdir
17395
17396 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17397         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17398         local facet=mds$((mdtidx + 1))
17399         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17400         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17401
17402         stop $facet || error "stop MDS failed"
17403         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17404                 error "start MDS fail"
17405         wait_recovery_complete $facet
17406 }
17407 run_test 257 "xattr locks are not lost"
17408
17409 # Verify we take the i_mutex when security requires it
17410 test_258a() {
17411 #define OBD_FAIL_IMUTEX_SEC 0x141c
17412         $LCTL set_param fail_loc=0x141c
17413         touch $DIR/$tfile
17414         chmod u+s $DIR/$tfile
17415         chmod a+rwx $DIR/$tfile
17416         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17417         RC=$?
17418         if [ $RC -ne 0 ]; then
17419                 error "error, failed to take i_mutex, rc=$?"
17420         fi
17421         rm -f $DIR/$tfile
17422 }
17423 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17424
17425 # Verify we do NOT take the i_mutex in the normal case
17426 test_258b() {
17427 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17428         $LCTL set_param fail_loc=0x141d
17429         touch $DIR/$tfile
17430         chmod a+rwx $DIR
17431         chmod a+rw $DIR/$tfile
17432         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17433         RC=$?
17434         if [ $RC -ne 0 ]; then
17435                 error "error, took i_mutex unnecessarily, rc=$?"
17436         fi
17437         rm -f $DIR/$tfile
17438
17439 }
17440 run_test 258b "verify i_mutex security behavior"
17441
17442 test_259() {
17443         local file=$DIR/$tfile
17444         local before
17445         local after
17446
17447         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17448
17449         stack_trap "rm -f $file" EXIT
17450
17451         wait_delete_completed
17452         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17453         echo "before: $before"
17454
17455         $LFS setstripe -i 0 -c 1 $file
17456         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17457         sync_all_data
17458         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17459         echo "after write: $after"
17460
17461 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17462         do_facet ost1 $LCTL set_param fail_loc=0x2301
17463         $TRUNCATE $file 0
17464         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17465         echo "after truncate: $after"
17466
17467         stop ost1
17468         do_facet ost1 $LCTL set_param fail_loc=0
17469         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17470         sleep 2
17471         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17472         echo "after restart: $after"
17473         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17474                 error "missing truncate?"
17475
17476         return 0
17477 }
17478 run_test 259 "crash at delayed truncate"
17479
17480 test_260() {
17481 #define OBD_FAIL_MDC_CLOSE               0x806
17482         $LCTL set_param fail_loc=0x80000806
17483         touch $DIR/$tfile
17484
17485 }
17486 run_test 260 "Check mdc_close fail"
17487
17488 ### Data-on-MDT sanity tests ###
17489 test_270a() {
17490         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17491                 skip "Need MDS version at least 2.10.55 for DoM"
17492
17493         # create DoM file
17494         local dom=$DIR/$tdir/dom_file
17495         local tmp=$DIR/$tdir/tmp_file
17496
17497         mkdir -p $DIR/$tdir
17498
17499         # basic checks for DoM component creation
17500         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17501                 error "Can set MDT layout to non-first entry"
17502
17503         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17504                 error "Can define multiple entries as MDT layout"
17505
17506         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17507
17508         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17509         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17510         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17511
17512         local mdtidx=$($LFS getstripe -m $dom)
17513         local mdtname=MDT$(printf %04x $mdtidx)
17514         local facet=mds$((mdtidx + 1))
17515         local space_check=1
17516
17517         # Skip free space checks with ZFS
17518         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17519
17520         # write
17521         sync
17522         local size_tmp=$((65536 * 3))
17523         local mdtfree1=$(do_facet $facet \
17524                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17525
17526         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17527         # check also direct IO along write
17528         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17529         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17530         sync
17531         cmp $tmp $dom || error "file data is different"
17532         [ $(stat -c%s $dom) == $size_tmp ] ||
17533                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17534         if [ $space_check == 1 ]; then
17535                 local mdtfree2=$(do_facet $facet \
17536                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17537
17538                 # increase in usage from by $size_tmp
17539                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17540                         error "MDT free space wrong after write: " \
17541                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17542         fi
17543
17544         # truncate
17545         local size_dom=10000
17546
17547         $TRUNCATE $dom $size_dom
17548         [ $(stat -c%s $dom) == $size_dom ] ||
17549                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17550         if [ $space_check == 1 ]; then
17551                 mdtfree1=$(do_facet $facet \
17552                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17553                 # decrease in usage from $size_tmp to new $size_dom
17554                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17555                   $(((size_tmp - size_dom) / 1024)) ] ||
17556                         error "MDT free space is wrong after truncate: " \
17557                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17558         fi
17559
17560         # append
17561         cat $tmp >> $dom
17562         sync
17563         size_dom=$((size_dom + size_tmp))
17564         [ $(stat -c%s $dom) == $size_dom ] ||
17565                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17566         if [ $space_check == 1 ]; then
17567                 mdtfree2=$(do_facet $facet \
17568                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17569                 # increase in usage by $size_tmp from previous
17570                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17571                         error "MDT free space is wrong after append: " \
17572                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17573         fi
17574
17575         # delete
17576         rm $dom
17577         if [ $space_check == 1 ]; then
17578                 mdtfree1=$(do_facet $facet \
17579                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17580                 # decrease in usage by $size_dom from previous
17581                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17582                         error "MDT free space is wrong after removal: " \
17583                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17584         fi
17585
17586         # combined striping
17587         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17588                 error "Can't create DoM + OST striping"
17589
17590         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17591         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17592         # check also direct IO along write
17593         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17594         sync
17595         cmp $tmp $dom || error "file data is different"
17596         [ $(stat -c%s $dom) == $size_tmp ] ||
17597                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17598         rm $dom $tmp
17599
17600         return 0
17601 }
17602 run_test 270a "DoM: basic functionality tests"
17603
17604 test_270b() {
17605         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17606                 skip "Need MDS version at least 2.10.55"
17607
17608         local dom=$DIR/$tdir/dom_file
17609         local max_size=1048576
17610
17611         mkdir -p $DIR/$tdir
17612         $LFS setstripe -E $max_size -L mdt $dom
17613
17614         # truncate over the limit
17615         $TRUNCATE $dom $(($max_size + 1)) &&
17616                 error "successful truncate over the maximum size"
17617         # write over the limit
17618         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17619                 error "successful write over the maximum size"
17620         # append over the limit
17621         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17622         echo "12345" >> $dom && error "successful append over the maximum size"
17623         rm $dom
17624
17625         return 0
17626 }
17627 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17628
17629 test_270c() {
17630         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17631                 skip "Need MDS version at least 2.10.55"
17632
17633         mkdir -p $DIR/$tdir
17634         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17635
17636         # check files inherit DoM EA
17637         touch $DIR/$tdir/first
17638         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17639                 error "bad pattern"
17640         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17641                 error "bad stripe count"
17642         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17643                 error "bad stripe size"
17644
17645         # check directory inherits DoM EA and uses it as default
17646         mkdir $DIR/$tdir/subdir
17647         touch $DIR/$tdir/subdir/second
17648         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17649                 error "bad pattern in sub-directory"
17650         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17651                 error "bad stripe count in sub-directory"
17652         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17653                 error "bad stripe size in sub-directory"
17654         return 0
17655 }
17656 run_test 270c "DoM: DoM EA inheritance tests"
17657
17658 test_270d() {
17659         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17660                 skip "Need MDS version at least 2.10.55"
17661
17662         mkdir -p $DIR/$tdir
17663         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17664
17665         # inherit default DoM striping
17666         mkdir $DIR/$tdir/subdir
17667         touch $DIR/$tdir/subdir/f1
17668
17669         # change default directory striping
17670         $LFS setstripe -c 1 $DIR/$tdir/subdir
17671         touch $DIR/$tdir/subdir/f2
17672         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17673                 error "wrong default striping in file 2"
17674         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17675                 error "bad pattern in file 2"
17676         return 0
17677 }
17678 run_test 270d "DoM: change striping from DoM to RAID0"
17679
17680 test_270e() {
17681         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17682                 skip "Need MDS version at least 2.10.55"
17683
17684         mkdir -p $DIR/$tdir/dom
17685         mkdir -p $DIR/$tdir/norm
17686         DOMFILES=20
17687         NORMFILES=10
17688         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17689         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17690
17691         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17692         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17693
17694         # find DoM files by layout
17695         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17696         [ $NUM -eq  $DOMFILES ] ||
17697                 error "lfs find -L: found $NUM, expected $DOMFILES"
17698         echo "Test 1: lfs find 20 DOM files by layout: OK"
17699
17700         # there should be 1 dir with default DOM striping
17701         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17702         [ $NUM -eq  1 ] ||
17703                 error "lfs find -L: found $NUM, expected 1 dir"
17704         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17705
17706         # find DoM files by stripe size
17707         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17708         [ $NUM -eq  $DOMFILES ] ||
17709                 error "lfs find -S: found $NUM, expected $DOMFILES"
17710         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17711
17712         # find files by stripe offset except DoM files
17713         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17714         [ $NUM -eq  $NORMFILES ] ||
17715                 error "lfs find -i: found $NUM, expected $NORMFILES"
17716         echo "Test 5: lfs find no DOM files by stripe index: OK"
17717         return 0
17718 }
17719 run_test 270e "DoM: lfs find with DoM files test"
17720
17721 test_270f() {
17722         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17723                 skip "Need MDS version at least 2.10.55"
17724
17725         local mdtname=${FSNAME}-MDT0000-mdtlov
17726         local dom=$DIR/$tdir/dom_file
17727         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17728                                                 lod.$mdtname.dom_stripesize)
17729         local dom_limit=131072
17730
17731         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17732         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17733                                                 lod.$mdtname.dom_stripesize)
17734         [ ${dom_limit} -eq ${dom_current} ] ||
17735                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17736
17737         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17738         $LFS setstripe -d $DIR/$tdir
17739         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17740                 error "Can't set directory default striping"
17741
17742         # exceed maximum stripe size
17743         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17744                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17745         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17746                 error "Able to create DoM component size more than LOD limit"
17747
17748         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17749         dom_current=$(do_facet mds1 $LCTL get_param -n \
17750                                                 lod.$mdtname.dom_stripesize)
17751         [ 0 -eq ${dom_current} ] ||
17752                 error "Can't set zero DoM stripe limit"
17753         rm $dom
17754
17755         # attempt to create DoM file on server with disabled DoM should
17756         # remove DoM entry from layout and be succeed
17757         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17758                 error "Can't create DoM file (DoM is disabled)"
17759         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17760                 error "File has DoM component while DoM is disabled"
17761         rm $dom
17762
17763         # attempt to create DoM file with only DoM stripe should return error
17764         $LFS setstripe -E $dom_limit -L mdt $dom &&
17765                 error "Able to create DoM-only file while DoM is disabled"
17766
17767         # too low values to be aligned with smallest stripe size 64K
17768         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17769         dom_current=$(do_facet mds1 $LCTL get_param -n \
17770                                                 lod.$mdtname.dom_stripesize)
17771         [ 30000 -eq ${dom_current} ] &&
17772                 error "Can set too small DoM stripe limit"
17773
17774         # 64K is a minimal stripe size in Lustre, expect limit of that size
17775         [ 65536 -eq ${dom_current} ] ||
17776                 error "Limit is not set to 64K but ${dom_current}"
17777
17778         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17779         dom_current=$(do_facet mds1 $LCTL get_param -n \
17780                                                 lod.$mdtname.dom_stripesize)
17781         echo $dom_current
17782         [ 2147483648 -eq ${dom_current} ] &&
17783                 error "Can set too large DoM stripe limit"
17784
17785         do_facet mds1 $LCTL set_param -n \
17786                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17787         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17788                 error "Can't create DoM component size after limit change"
17789         do_facet mds1 $LCTL set_param -n \
17790                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17791         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17792                 error "Can't create DoM file after limit decrease"
17793         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17794                 error "Can create big DoM component after limit decrease"
17795         touch ${dom}_def ||
17796                 error "Can't create file with old default layout"
17797
17798         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17799         return 0
17800 }
17801 run_test 270f "DoM: maximum DoM stripe size checks"
17802
17803 test_271a() {
17804         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17805                 skip "Need MDS version at least 2.10.55"
17806
17807         local dom=$DIR/$tdir/dom
17808
17809         mkdir -p $DIR/$tdir
17810
17811         $LFS setstripe -E 1024K -L mdt $dom
17812
17813         lctl set_param -n mdc.*.stats=clear
17814         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17815         cat $dom > /dev/null
17816         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
17817         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
17818         ls $dom
17819         rm -f $dom
17820 }
17821 run_test 271a "DoM: data is cached for read after write"
17822
17823 test_271b() {
17824         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17825                 skip "Need MDS version at least 2.10.55"
17826
17827         local dom=$DIR/$tdir/dom
17828
17829         mkdir -p $DIR/$tdir
17830
17831         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17832
17833         lctl set_param -n mdc.*.stats=clear
17834         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
17835         cancel_lru_locks mdc
17836         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
17837         # second stat to check size is cached on client
17838         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
17839         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17840         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
17841         rm -f $dom
17842 }
17843 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
17844
17845 test_271ba() {
17846         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17847                 skip "Need MDS version at least 2.10.55"
17848
17849         local dom=$DIR/$tdir/dom
17850
17851         mkdir -p $DIR/$tdir
17852
17853         $LFS setstripe -E 1024K -L mdt -E EOF $dom
17854
17855         lctl set_param -n mdc.*.stats=clear
17856         lctl set_param -n osc.*.stats=clear
17857         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
17858         cancel_lru_locks mdc
17859         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17860         # second stat to check size is cached on client
17861         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
17862         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
17863         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
17864         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
17865         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
17866         rm -f $dom
17867 }
17868 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
17869
17870
17871 get_mdc_stats() {
17872         local mdtidx=$1
17873         local param=$2
17874         local mdt=MDT$(printf %04x $mdtidx)
17875
17876         if [ -z $param ]; then
17877                 lctl get_param -n mdc.*$mdt*.stats
17878         else
17879                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
17880         fi
17881 }
17882
17883 test_271c() {
17884         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17885                 skip "Need MDS version at least 2.10.55"
17886
17887         local dom=$DIR/$tdir/dom
17888
17889         mkdir -p $DIR/$tdir
17890
17891         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17892
17893         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17894         local facet=mds$((mdtidx + 1))
17895
17896         cancel_lru_locks mdc
17897         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
17898         createmany -o $dom 1000
17899         lctl set_param -n mdc.*.stats=clear
17900         smalliomany -w $dom 1000 200
17901         get_mdc_stats $mdtidx
17902         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17903         # Each file has 1 open, 1 IO enqueues, total 2000
17904         # but now we have also +1 getxattr for security.capability, total 3000
17905         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
17906         unlinkmany $dom 1000
17907
17908         cancel_lru_locks mdc
17909         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
17910         createmany -o $dom 1000
17911         lctl set_param -n mdc.*.stats=clear
17912         smalliomany -w $dom 1000 200
17913         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
17914         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
17915         # for OPEN and IO lock.
17916         [ $((enq - enq_2)) -ge 1000 ] ||
17917                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
17918         unlinkmany $dom 1000
17919         return 0
17920 }
17921 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
17922
17923 cleanup_271def_tests() {
17924         trap 0
17925         rm -f $1
17926 }
17927
17928 test_271d() {
17929         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17930                 skip "Need MDS version at least 2.10.57"
17931
17932         local dom=$DIR/$tdir/dom
17933         local tmp=$TMP/$tfile
17934         trap "cleanup_271def_tests $tmp" EXIT
17935
17936         mkdir -p $DIR/$tdir
17937
17938         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17939
17940         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17941
17942         cancel_lru_locks mdc
17943         dd if=/dev/urandom of=$tmp bs=1000 count=1
17944         dd if=$tmp of=$dom bs=1000 count=1
17945         cancel_lru_locks mdc
17946
17947         cat /etc/hosts >> $tmp
17948         lctl set_param -n mdc.*.stats=clear
17949
17950         # append data to the same file it should update local page
17951         echo "Append to the same page"
17952         cat /etc/hosts >> $dom
17953         local num=$(get_mdc_stats $mdtidx ost_read)
17954         local ra=$(get_mdc_stats $mdtidx req_active)
17955         local rw=$(get_mdc_stats $mdtidx req_waittime)
17956
17957         [ -z $num ] || error "$num READ RPC occured"
17958         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17959         echo "... DONE"
17960
17961         # compare content
17962         cmp $tmp $dom || error "file miscompare"
17963
17964         cancel_lru_locks mdc
17965         lctl set_param -n mdc.*.stats=clear
17966
17967         echo "Open and read file"
17968         cat $dom > /dev/null
17969         local num=$(get_mdc_stats $mdtidx ost_read)
17970         local ra=$(get_mdc_stats $mdtidx req_active)
17971         local rw=$(get_mdc_stats $mdtidx req_waittime)
17972
17973         [ -z $num ] || error "$num READ RPC occured"
17974         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
17975         echo "... DONE"
17976
17977         # compare content
17978         cmp $tmp $dom || error "file miscompare"
17979
17980         return 0
17981 }
17982 run_test 271d "DoM: read on open (1K file in reply buffer)"
17983
17984 test_271f() {
17985         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
17986                 skip "Need MDS version at least 2.10.57"
17987
17988         local dom=$DIR/$tdir/dom
17989         local tmp=$TMP/$tfile
17990         trap "cleanup_271def_tests $tmp" EXIT
17991
17992         mkdir -p $DIR/$tdir
17993
17994         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17995
17996         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
17997
17998         cancel_lru_locks mdc
17999         dd if=/dev/urandom of=$tmp bs=200000 count=1
18000         dd if=$tmp of=$dom bs=200000 count=1
18001         cancel_lru_locks mdc
18002         cat /etc/hosts >> $tmp
18003         lctl set_param -n mdc.*.stats=clear
18004
18005         echo "Append to the same page"
18006         cat /etc/hosts >> $dom
18007         local num=$(get_mdc_stats $mdtidx ost_read)
18008         local ra=$(get_mdc_stats $mdtidx req_active)
18009         local rw=$(get_mdc_stats $mdtidx req_waittime)
18010
18011         [ -z $num ] || error "$num READ RPC occured"
18012         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18013         echo "... DONE"
18014
18015         # compare content
18016         cmp $tmp $dom || error "file miscompare"
18017
18018         cancel_lru_locks mdc
18019         lctl set_param -n mdc.*.stats=clear
18020
18021         echo "Open and read file"
18022         cat $dom > /dev/null
18023         local num=$(get_mdc_stats $mdtidx ost_read)
18024         local ra=$(get_mdc_stats $mdtidx req_active)
18025         local rw=$(get_mdc_stats $mdtidx req_waittime)
18026
18027         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18028         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18029         echo "... DONE"
18030
18031         # compare content
18032         cmp $tmp $dom || error "file miscompare"
18033
18034         return 0
18035 }
18036 run_test 271f "DoM: read on open (200K file and read tail)"
18037
18038 test_271g() {
18039         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18040                 skip "Skipping due to old client or server version"
18041
18042         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18043         # to get layout
18044         $CHECKSTAT -t file $DIR1/$tfile
18045
18046         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18047         MULTIOP_PID=$!
18048         sleep 1
18049         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18050         $LCTL set_param fail_loc=0x80000314
18051         rm $DIR1/$tfile || error "Unlink fails"
18052         RC=$?
18053         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18054         [ $RC -eq 0 ] || error "Failed write to stale object"
18055 }
18056 run_test 271g "Discard DoM data vs client flush race"
18057
18058 test_272a() {
18059         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18060                 skip "Need MDS version at least 2.11.50"
18061
18062         local dom=$DIR/$tdir/dom
18063         mkdir -p $DIR/$tdir
18064
18065         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18066         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18067                 error "failed to write data into $dom"
18068         local old_md5=$(md5sum $dom)
18069
18070         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18071                 error "failed to migrate to the same DoM component"
18072
18073         local new_md5=$(md5sum $dom)
18074
18075         [ "$old_md5" == "$new_md5" ] ||
18076                 error "md5sum differ: $old_md5, $new_md5"
18077
18078         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18079                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18080 }
18081 run_test 272a "DoM migration: new layout with the same DOM component"
18082
18083 test_272b() {
18084         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18085                 skip "Need MDS version at least 2.11.50"
18086
18087         local dom=$DIR/$tdir/dom
18088         mkdir -p $DIR/$tdir
18089         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18090
18091         local mdtidx=$($LFS getstripe -m $dom)
18092         local mdtname=MDT$(printf %04x $mdtidx)
18093         local facet=mds$((mdtidx + 1))
18094
18095         local mdtfree1=$(do_facet $facet \
18096                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18097         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18098                 error "failed to write data into $dom"
18099         local old_md5=$(md5sum $dom)
18100         cancel_lru_locks mdc
18101         local mdtfree1=$(do_facet $facet \
18102                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18103
18104         $LFS migrate -c2 $dom ||
18105                 error "failed to migrate to the new composite layout"
18106         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18107                 error "MDT stripe was not removed"
18108
18109         cancel_lru_locks mdc
18110         local new_md5=$(md5sum $dom)
18111         [ "$old_md5" != "$new_md5" ] &&
18112                 error "$old_md5 != $new_md5"
18113
18114         # Skip free space checks with ZFS
18115         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18116                 local mdtfree2=$(do_facet $facet \
18117                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18118                 [ $mdtfree2 -gt $mdtfree1 ] ||
18119                         error "MDT space is not freed after migration"
18120         fi
18121         return 0
18122 }
18123 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18124
18125 test_272c() {
18126         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18127                 skip "Need MDS version at least 2.11.50"
18128
18129         local dom=$DIR/$tdir/$tfile
18130         mkdir -p $DIR/$tdir
18131         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18132
18133         local mdtidx=$($LFS getstripe -m $dom)
18134         local mdtname=MDT$(printf %04x $mdtidx)
18135         local facet=mds$((mdtidx + 1))
18136
18137         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18138                 error "failed to write data into $dom"
18139         local old_md5=$(md5sum $dom)
18140         cancel_lru_locks mdc
18141         local mdtfree1=$(do_facet $facet \
18142                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18143
18144         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18145                 error "failed to migrate to the new composite layout"
18146         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18147                 error "MDT stripe was not removed"
18148
18149         cancel_lru_locks mdc
18150         local new_md5=$(md5sum $dom)
18151         [ "$old_md5" != "$new_md5" ] &&
18152                 error "$old_md5 != $new_md5"
18153
18154         # Skip free space checks with ZFS
18155         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18156                 local mdtfree2=$(do_facet $facet \
18157                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18158                 [ $mdtfree2 -gt $mdtfree1 ] ||
18159                         error "MDS space is not freed after migration"
18160         fi
18161         return 0
18162 }
18163 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18164
18165 test_273a() {
18166         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18167                 skip "Need MDS version at least 2.11.50"
18168
18169         # Layout swap cannot be done if either file has DOM component,
18170         # this will never be supported, migration should be used instead
18171
18172         local dom=$DIR/$tdir/$tfile
18173         mkdir -p $DIR/$tdir
18174
18175         $LFS setstripe -c2 ${dom}_plain
18176         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18177         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18178                 error "can swap layout with DoM component"
18179         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18180                 error "can swap layout with DoM component"
18181
18182         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18183         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18184                 error "can swap layout with DoM component"
18185         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18186                 error "can swap layout with DoM component"
18187         return 0
18188 }
18189 run_test 273a "DoM: layout swapping should fail with DOM"
18190
18191 test_275() {
18192         remote_ost_nodsh && skip "remote OST with nodsh"
18193         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18194                 skip "Need OST version >= 2.10.57"
18195
18196         local file=$DIR/$tfile
18197         local oss
18198
18199         oss=$(comma_list $(osts_nodes))
18200
18201         dd if=/dev/urandom of=$file bs=1M count=2 ||
18202                 error "failed to create a file"
18203         cancel_lru_locks osc
18204
18205         #lock 1
18206         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18207                 error "failed to read a file"
18208
18209 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18210         $LCTL set_param fail_loc=0x8000031f
18211
18212         cancel_lru_locks osc &
18213         sleep 1
18214
18215 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18216         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18217         #IO takes another lock, but matches the PENDING one
18218         #and places it to the IO RPC
18219         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18220                 error "failed to read a file with PENDING lock"
18221 }
18222 run_test 275 "Read on a canceled duplicate lock"
18223
18224 test_276() {
18225         remote_ost_nodsh && skip "remote OST with nodsh"
18226         local pid
18227
18228         do_facet ost1 "(while true; do \
18229                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18230                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18231         pid=$!
18232
18233         for LOOP in $(seq 20); do
18234                 stop ost1
18235                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18236         done
18237         kill -9 $pid
18238         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18239                 rm $TMP/sanity_276_pid"
18240 }
18241 run_test 276 "Race between mount and obd_statfs"
18242
18243 cleanup_test_300() {
18244         trap 0
18245         umask $SAVE_UMASK
18246 }
18247 test_striped_dir() {
18248         local mdt_index=$1
18249         local stripe_count
18250         local stripe_index
18251
18252         mkdir -p $DIR/$tdir
18253
18254         SAVE_UMASK=$(umask)
18255         trap cleanup_test_300 RETURN EXIT
18256
18257         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18258                                                 $DIR/$tdir/striped_dir ||
18259                 error "set striped dir error"
18260
18261         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18262         [ "$mode" = "755" ] || error "expect 755 got $mode"
18263
18264         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18265                 error "getdirstripe failed"
18266         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18267         if [ "$stripe_count" != "2" ]; then
18268                 error "1:stripe_count is $stripe_count, expect 2"
18269         fi
18270         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18271         if [ "$stripe_count" != "2" ]; then
18272                 error "2:stripe_count is $stripe_count, expect 2"
18273         fi
18274
18275         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18276         if [ "$stripe_index" != "$mdt_index" ]; then
18277                 error "stripe_index is $stripe_index, expect $mdt_index"
18278         fi
18279
18280         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18281                 error "nlink error after create striped dir"
18282
18283         mkdir $DIR/$tdir/striped_dir/a
18284         mkdir $DIR/$tdir/striped_dir/b
18285
18286         stat $DIR/$tdir/striped_dir/a ||
18287                 error "create dir under striped dir failed"
18288         stat $DIR/$tdir/striped_dir/b ||
18289                 error "create dir under striped dir failed"
18290
18291         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18292                 error "nlink error after mkdir"
18293
18294         rmdir $DIR/$tdir/striped_dir/a
18295         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18296                 error "nlink error after rmdir"
18297
18298         rmdir $DIR/$tdir/striped_dir/b
18299         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18300                 error "nlink error after rmdir"
18301
18302         chattr +i $DIR/$tdir/striped_dir
18303         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18304                 error "immutable flags not working under striped dir!"
18305         chattr -i $DIR/$tdir/striped_dir
18306
18307         rmdir $DIR/$tdir/striped_dir ||
18308                 error "rmdir striped dir error"
18309
18310         cleanup_test_300
18311
18312         true
18313 }
18314
18315 test_300a() {
18316         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18317                 skip "skipped for lustre < 2.7.0"
18318         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18319         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18320
18321         test_striped_dir 0 || error "failed on striped dir on MDT0"
18322         test_striped_dir 1 || error "failed on striped dir on MDT0"
18323 }
18324 run_test 300a "basic striped dir sanity test"
18325
18326 test_300b() {
18327         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18328                 skip "skipped for lustre < 2.7.0"
18329         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18330         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18331
18332         local i
18333         local mtime1
18334         local mtime2
18335         local mtime3
18336
18337         test_mkdir $DIR/$tdir || error "mkdir fail"
18338         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18339                 error "set striped dir error"
18340         for i in {0..9}; do
18341                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18342                 sleep 1
18343                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18344                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18345                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18346                 sleep 1
18347                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18348                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18349                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18350         done
18351         true
18352 }
18353 run_test 300b "check ctime/mtime for striped dir"
18354
18355 test_300c() {
18356         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18357                 skip "skipped for lustre < 2.7.0"
18358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18359         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18360
18361         local file_count
18362
18363         mkdir -p $DIR/$tdir
18364         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18365                 error "set striped dir error"
18366
18367         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18368                 error "chown striped dir failed"
18369
18370         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18371                 error "create 5k files failed"
18372
18373         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18374
18375         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18376
18377         rm -rf $DIR/$tdir
18378 }
18379 run_test 300c "chown && check ls under striped directory"
18380
18381 test_300d() {
18382         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18383                 skip "skipped for lustre < 2.7.0"
18384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18385         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18386
18387         local stripe_count
18388         local file
18389
18390         mkdir -p $DIR/$tdir
18391         $LFS setstripe -c 2 $DIR/$tdir
18392
18393         #local striped directory
18394         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18395                 error "set striped dir error"
18396         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18397                 error "create 10 files failed"
18398
18399         #remote striped directory
18400         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18401                 error "set striped dir error"
18402         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18403                 error "create 10 files failed"
18404
18405         for file in $(find $DIR/$tdir); do
18406                 stripe_count=$($LFS getstripe -c $file)
18407                 [ $stripe_count -eq 2 ] ||
18408                         error "wrong stripe $stripe_count for $file"
18409         done
18410
18411         rm -rf $DIR/$tdir
18412 }
18413 run_test 300d "check default stripe under striped directory"
18414
18415 test_300e() {
18416         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18417                 skip "Need MDS version at least 2.7.55"
18418         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18419         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18420
18421         local stripe_count
18422         local file
18423
18424         mkdir -p $DIR/$tdir
18425
18426         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18427                 error "set striped dir error"
18428
18429         touch $DIR/$tdir/striped_dir/a
18430         touch $DIR/$tdir/striped_dir/b
18431         touch $DIR/$tdir/striped_dir/c
18432
18433         mkdir $DIR/$tdir/striped_dir/dir_a
18434         mkdir $DIR/$tdir/striped_dir/dir_b
18435         mkdir $DIR/$tdir/striped_dir/dir_c
18436
18437         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18438                 error "set striped adir under striped dir error"
18439
18440         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18441                 error "set striped bdir under striped dir error"
18442
18443         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18444                 error "set striped cdir under striped dir error"
18445
18446         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18447                 error "rename dir under striped dir fails"
18448
18449         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18450                 error "rename dir under different stripes fails"
18451
18452         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18453                 error "rename file under striped dir should succeed"
18454
18455         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18456                 error "rename dir under striped dir should succeed"
18457
18458         rm -rf $DIR/$tdir
18459 }
18460 run_test 300e "check rename under striped directory"
18461
18462 test_300f() {
18463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18465         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18466                 skip "Need MDS version at least 2.7.55"
18467
18468         local stripe_count
18469         local file
18470
18471         rm -rf $DIR/$tdir
18472         mkdir -p $DIR/$tdir
18473
18474         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18475                 error "set striped dir error"
18476
18477         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18478                 error "set striped dir error"
18479
18480         touch $DIR/$tdir/striped_dir/a
18481         mkdir $DIR/$tdir/striped_dir/dir_a
18482         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18483                 error "create striped dir under striped dir fails"
18484
18485         touch $DIR/$tdir/striped_dir1/b
18486         mkdir $DIR/$tdir/striped_dir1/dir_b
18487         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18488                 error "create striped dir under striped dir fails"
18489
18490         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18491                 error "rename dir under different striped dir should fail"
18492
18493         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18494                 error "rename striped dir under diff striped dir should fail"
18495
18496         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18497                 error "rename file under diff striped dirs fails"
18498
18499         rm -rf $DIR/$tdir
18500 }
18501 run_test 300f "check rename cross striped directory"
18502
18503 test_300_check_default_striped_dir()
18504 {
18505         local dirname=$1
18506         local default_count=$2
18507         local default_index=$3
18508         local stripe_count
18509         local stripe_index
18510         local dir_stripe_index
18511         local dir
18512
18513         echo "checking $dirname $default_count $default_index"
18514         $LFS setdirstripe -D -c $default_count -i $default_index \
18515                                 -t all_char $DIR/$tdir/$dirname ||
18516                 error "set default stripe on striped dir error"
18517         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18518         [ $stripe_count -eq $default_count ] ||
18519                 error "expect $default_count get $stripe_count for $dirname"
18520
18521         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18522         [ $stripe_index -eq $default_index ] ||
18523                 error "expect $default_index get $stripe_index for $dirname"
18524
18525         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18526                                                 error "create dirs failed"
18527
18528         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18529         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18530         for dir in $(find $DIR/$tdir/$dirname/*); do
18531                 stripe_count=$($LFS getdirstripe -c $dir)
18532                 [ $stripe_count -eq $default_count ] ||
18533                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18534                 error "stripe count $default_count != $stripe_count for $dir"
18535
18536                 stripe_index=$($LFS getdirstripe -i $dir)
18537                 [ $default_index -eq -1 ] ||
18538                         [ $stripe_index -eq $default_index ] ||
18539                         error "$stripe_index != $default_index for $dir"
18540
18541                 #check default stripe
18542                 stripe_count=$($LFS getdirstripe -D -c $dir)
18543                 [ $stripe_count -eq $default_count ] ||
18544                 error "default count $default_count != $stripe_count for $dir"
18545
18546                 stripe_index=$($LFS getdirstripe -D -i $dir)
18547                 [ $stripe_index -eq $default_index ] ||
18548                 error "default index $default_index != $stripe_index for $dir"
18549         done
18550         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18551 }
18552
18553 test_300g() {
18554         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18555         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18556                 skip "Need MDS version at least 2.7.55"
18557
18558         local dir
18559         local stripe_count
18560         local stripe_index
18561
18562         mkdir $DIR/$tdir
18563         mkdir $DIR/$tdir/normal_dir
18564
18565         #Checking when client cache stripe index
18566         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18567         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18568                 error "create striped_dir failed"
18569
18570         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18571                 error "create dir0 fails"
18572         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18573         [ $stripe_index -eq 0 ] ||
18574                 error "dir0 expect index 0 got $stripe_index"
18575
18576         mkdir $DIR/$tdir/striped_dir/dir1 ||
18577                 error "create dir1 fails"
18578         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18579         [ $stripe_index -eq 1 ] ||
18580                 error "dir1 expect index 1 got $stripe_index"
18581
18582         #check default stripe count/stripe index
18583         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18584         test_300_check_default_striped_dir normal_dir 1 0
18585         test_300_check_default_striped_dir normal_dir 2 1
18586         test_300_check_default_striped_dir normal_dir 2 -1
18587
18588         #delete default stripe information
18589         echo "delete default stripeEA"
18590         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18591                 error "set default stripe on striped dir error"
18592
18593         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18594         for dir in $(find $DIR/$tdir/normal_dir/*); do
18595                 stripe_count=$($LFS getdirstripe -c $dir)
18596                 [ $stripe_count -eq 0 ] ||
18597                         error "expect 1 get $stripe_count for $dir"
18598                 stripe_index=$($LFS getdirstripe -i $dir)
18599                 [ $stripe_index -eq 0 ] ||
18600                         error "expect 0 get $stripe_index for $dir"
18601         done
18602 }
18603 run_test 300g "check default striped directory for normal directory"
18604
18605 test_300h() {
18606         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18607         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18608                 skip "Need MDS version at least 2.7.55"
18609
18610         local dir
18611         local stripe_count
18612
18613         mkdir $DIR/$tdir
18614         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18615                 error "set striped dir error"
18616
18617         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18618         test_300_check_default_striped_dir striped_dir 1 0
18619         test_300_check_default_striped_dir striped_dir 2 1
18620         test_300_check_default_striped_dir striped_dir 2 -1
18621
18622         #delete default stripe information
18623         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18624                 error "set default stripe on striped dir error"
18625
18626         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18627         for dir in $(find $DIR/$tdir/striped_dir/*); do
18628                 stripe_count=$($LFS getdirstripe -c $dir)
18629                 [ $stripe_count -eq 0 ] ||
18630                         error "expect 1 get $stripe_count for $dir"
18631         done
18632 }
18633 run_test 300h "check default striped directory for striped directory"
18634
18635 test_300i() {
18636         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18637         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18638         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18639                 skip "Need MDS version at least 2.7.55"
18640
18641         local stripe_count
18642         local file
18643
18644         mkdir $DIR/$tdir
18645
18646         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18647                 error "set striped dir error"
18648
18649         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18650                 error "create files under striped dir failed"
18651
18652         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18653                 error "set striped hashdir error"
18654
18655         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18656                 error "create dir0 under hash dir failed"
18657         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18658                 error "create dir1 under hash dir failed"
18659
18660         # unfortunately, we need to umount to clear dir layout cache for now
18661         # once we fully implement dir layout, we can drop this
18662         umount_client $MOUNT || error "umount failed"
18663         mount_client $MOUNT || error "mount failed"
18664
18665         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18666         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18667         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18668
18669         #set the stripe to be unknown hash type
18670         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18671         $LCTL set_param fail_loc=0x1901
18672         for ((i = 0; i < 10; i++)); do
18673                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18674                         error "stat f-$i failed"
18675                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18676         done
18677
18678         touch $DIR/$tdir/striped_dir/f0 &&
18679                 error "create under striped dir with unknown hash should fail"
18680
18681         $LCTL set_param fail_loc=0
18682
18683         umount_client $MOUNT || error "umount failed"
18684         mount_client $MOUNT || error "mount failed"
18685
18686         return 0
18687 }
18688 run_test 300i "client handle unknown hash type striped directory"
18689
18690 test_300j() {
18691         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18693         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18694                 skip "Need MDS version at least 2.7.55"
18695
18696         local stripe_count
18697         local file
18698
18699         mkdir $DIR/$tdir
18700
18701         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18702         $LCTL set_param fail_loc=0x1702
18703         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18704                 error "set striped dir error"
18705
18706         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18707                 error "create files under striped dir failed"
18708
18709         $LCTL set_param fail_loc=0
18710
18711         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18712
18713         return 0
18714 }
18715 run_test 300j "test large update record"
18716
18717 test_300k() {
18718         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18719         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18720         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18721                 skip "Need MDS version at least 2.7.55"
18722
18723         # this test needs a huge transaction
18724         local kb
18725         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18726         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18727
18728         local stripe_count
18729         local file
18730
18731         mkdir $DIR/$tdir
18732
18733         #define OBD_FAIL_LARGE_STRIPE   0x1703
18734         $LCTL set_param fail_loc=0x1703
18735         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18736                 error "set striped dir error"
18737         $LCTL set_param fail_loc=0
18738
18739         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18740                 error "getstripeddir fails"
18741         rm -rf $DIR/$tdir/striped_dir ||
18742                 error "unlink striped dir fails"
18743
18744         return 0
18745 }
18746 run_test 300k "test large striped directory"
18747
18748 test_300l() {
18749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18750         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18751         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18752                 skip "Need MDS version at least 2.7.55"
18753
18754         local stripe_index
18755
18756         test_mkdir -p $DIR/$tdir/striped_dir
18757         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18758                         error "chown $RUNAS_ID failed"
18759         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18760                 error "set default striped dir failed"
18761
18762         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18763         $LCTL set_param fail_loc=0x80000158
18764         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18765
18766         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18767         [ $stripe_index -eq 1 ] ||
18768                 error "expect 1 get $stripe_index for $dir"
18769 }
18770 run_test 300l "non-root user to create dir under striped dir with stale layout"
18771
18772 test_300m() {
18773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18774         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18775         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18776                 skip "Need MDS version at least 2.7.55"
18777
18778         mkdir -p $DIR/$tdir/striped_dir
18779         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18780                 error "set default stripes dir error"
18781
18782         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18783
18784         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18785         [ $stripe_count -eq 0 ] ||
18786                         error "expect 0 get $stripe_count for a"
18787
18788         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18789                 error "set default stripes dir error"
18790
18791         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
18792
18793         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
18794         [ $stripe_count -eq 0 ] ||
18795                         error "expect 0 get $stripe_count for b"
18796
18797         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
18798                 error "set default stripes dir error"
18799
18800         mkdir $DIR/$tdir/striped_dir/c &&
18801                 error "default stripe_index is invalid, mkdir c should fails"
18802
18803         rm -rf $DIR/$tdir || error "rmdir fails"
18804 }
18805 run_test 300m "setstriped directory on single MDT FS"
18806
18807 cleanup_300n() {
18808         local list=$(comma_list $(mdts_nodes))
18809
18810         trap 0
18811         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18812 }
18813
18814 test_300n() {
18815         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18816         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18817         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18818                 skip "Need MDS version at least 2.7.55"
18819         remote_mds_nodsh && skip "remote MDS with nodsh"
18820
18821         local stripe_index
18822         local list=$(comma_list $(mdts_nodes))
18823
18824         trap cleanup_300n RETURN EXIT
18825         mkdir -p $DIR/$tdir
18826         chmod 777 $DIR/$tdir
18827         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
18828                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18829                 error "create striped dir succeeds with gid=0"
18830
18831         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18832         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
18833                 error "create striped dir fails with gid=-1"
18834
18835         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18836         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
18837                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
18838                 error "set default striped dir succeeds with gid=0"
18839
18840
18841         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
18842         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
18843                 error "set default striped dir fails with gid=-1"
18844
18845
18846         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
18847         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
18848                                         error "create test_dir fails"
18849         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
18850                                         error "create test_dir1 fails"
18851         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
18852                                         error "create test_dir2 fails"
18853         cleanup_300n
18854 }
18855 run_test 300n "non-root user to create dir under striped dir with default EA"
18856
18857 test_300o() {
18858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18859         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18860         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18861                 skip "Need MDS version at least 2.7.55"
18862
18863         local numfree1
18864         local numfree2
18865
18866         mkdir -p $DIR/$tdir
18867
18868         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
18869         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
18870         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
18871                 skip "not enough free inodes $numfree1 $numfree2"
18872         fi
18873
18874         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
18875         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
18876         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
18877                 skip "not enough free space $numfree1 $numfree2"
18878         fi
18879
18880         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
18881                 error "setdirstripe fails"
18882
18883         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
18884                 error "create dirs fails"
18885
18886         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
18887         ls $DIR/$tdir/striped_dir > /dev/null ||
18888                 error "ls striped dir fails"
18889         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
18890                 error "unlink big striped dir fails"
18891 }
18892 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
18893
18894 test_300p() {
18895         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18896         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18897         remote_mds_nodsh && skip "remote MDS with nodsh"
18898
18899         mkdir -p $DIR/$tdir
18900
18901         #define OBD_FAIL_OUT_ENOSPC     0x1704
18902         do_facet mds2 lctl set_param fail_loc=0x80001704
18903         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
18904                  && error "create striped directory should fail"
18905
18906         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
18907
18908         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
18909         true
18910 }
18911 run_test 300p "create striped directory without space"
18912
18913 test_300q() {
18914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18915         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18916
18917         local fd=$(free_fd)
18918         local cmd="exec $fd<$tdir"
18919         cd $DIR
18920         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
18921         eval $cmd
18922         cmd="exec $fd<&-"
18923         trap "eval $cmd" EXIT
18924         cd $tdir || error "cd $tdir fails"
18925         rmdir  ../$tdir || error "rmdir $tdir fails"
18926         mkdir local_dir && error "create dir succeeds"
18927         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
18928         eval $cmd
18929         return 0
18930 }
18931 run_test 300q "create remote directory under orphan directory"
18932
18933 test_300r() {
18934         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
18935                 skip "Need MDS version at least 2.7.55" && return
18936         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18937
18938         mkdir $DIR/$tdir
18939
18940         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
18941                 error "set striped dir error"
18942
18943         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18944                 error "getstripeddir fails"
18945
18946         local stripe_count
18947         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
18948                       awk '/lmv_stripe_count:/ { print $2 }')
18949
18950         [ $MDSCOUNT -ne $stripe_count ] &&
18951                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
18952
18953         rm -rf $DIR/$tdir/striped_dir ||
18954                 error "unlink striped dir fails"
18955 }
18956 run_test 300r "test -1 striped directory"
18957
18958 prepare_remote_file() {
18959         mkdir $DIR/$tdir/src_dir ||
18960                 error "create remote source failed"
18961
18962         cp /etc/hosts $DIR/$tdir/src_dir/a ||
18963                  error "cp to remote source failed"
18964         touch $DIR/$tdir/src_dir/a
18965
18966         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
18967                 error "create remote target dir failed"
18968
18969         touch $DIR/$tdir/tgt_dir/b
18970
18971         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
18972                 error "rename dir cross MDT failed!"
18973
18974         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
18975                 error "src_child still exists after rename"
18976
18977         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
18978                 error "missing file(a) after rename"
18979
18980         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
18981                 error "diff after rename"
18982 }
18983
18984 test_310a() {
18985         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
18986         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18987
18988         local remote_file=$DIR/$tdir/tgt_dir/b
18989
18990         mkdir -p $DIR/$tdir
18991
18992         prepare_remote_file || error "prepare remote file failed"
18993
18994         #open-unlink file
18995         $OPENUNLINK $remote_file $remote_file ||
18996                 error "openunlink $remote_file failed"
18997         $CHECKSTAT -a $remote_file || error "$remote_file exists"
18998 }
18999 run_test 310a "open unlink remote file"
19000
19001 test_310b() {
19002         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19003         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19004
19005         local remote_file=$DIR/$tdir/tgt_dir/b
19006
19007         mkdir -p $DIR/$tdir
19008
19009         prepare_remote_file || error "prepare remote file failed"
19010
19011         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19012         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19013         $CHECKSTAT -t file $remote_file || error "check file failed"
19014 }
19015 run_test 310b "unlink remote file with multiple links while open"
19016
19017 test_310c() {
19018         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19019         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19020
19021         local remote_file=$DIR/$tdir/tgt_dir/b
19022
19023         mkdir -p $DIR/$tdir
19024
19025         prepare_remote_file || error "prepare remote file failed"
19026
19027         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19028         multiop_bg_pause $remote_file O_uc ||
19029                         error "mulitop failed for remote file"
19030         MULTIPID=$!
19031         $MULTIOP $DIR/$tfile Ouc
19032         kill -USR1 $MULTIPID
19033         wait $MULTIPID
19034 }
19035 run_test 310c "open-unlink remote file with multiple links"
19036
19037 #LU-4825
19038 test_311() {
19039         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19040         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19041         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19042                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19043         remote_mds_nodsh && skip "remote MDS with nodsh"
19044
19045         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19046         local mdts=$(comma_list $(mdts_nodes))
19047
19048         mkdir -p $DIR/$tdir
19049         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19050         createmany -o $DIR/$tdir/$tfile. 1000
19051
19052         # statfs data is not real time, let's just calculate it
19053         old_iused=$((old_iused + 1000))
19054
19055         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19056                         osp.*OST0000*MDT0000.create_count")
19057         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19058                                 osp.*OST0000*MDT0000.max_create_count")
19059         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19060
19061         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19062         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19063         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19064
19065         unlinkmany $DIR/$tdir/$tfile. 1000
19066
19067         do_nodes $mdts "$LCTL set_param -n \
19068                         osp.*OST0000*.max_create_count=$max_count"
19069         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19070                 do_nodes $mdts "$LCTL set_param -n \
19071                                 osp.*OST0000*.create_count=$count"
19072         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19073                         grep "=0" && error "create_count is zero"
19074
19075         local new_iused
19076         for i in $(seq 120); do
19077                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19078                 # system may be too busy to destroy all objs in time, use
19079                 # a somewhat small value to not fail autotest
19080                 [ $((old_iused - new_iused)) -gt 400 ] && break
19081                 sleep 1
19082         done
19083
19084         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19085         [ $((old_iused - new_iused)) -gt 400 ] ||
19086                 error "objs not destroyed after unlink"
19087 }
19088 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19089
19090 zfs_oid_to_objid()
19091 {
19092         local ost=$1
19093         local objid=$2
19094
19095         local vdevdir=$(dirname $(facet_vdevice $ost))
19096         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19097         local zfs_zapid=$(do_facet $ost $cmd |
19098                           grep -w "/O/0/d$((objid%32))" -C 5 |
19099                           awk '/Object/{getline; print $1}')
19100         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19101                           awk "/$objid = /"'{printf $3}')
19102
19103         echo $zfs_objid
19104 }
19105
19106 zfs_object_blksz() {
19107         local ost=$1
19108         local objid=$2
19109
19110         local vdevdir=$(dirname $(facet_vdevice $ost))
19111         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19112         local blksz=$(do_facet $ost $cmd $objid |
19113                       awk '/dblk/{getline; printf $4}')
19114
19115         case "${blksz: -1}" in
19116                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19117                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19118                 *) ;;
19119         esac
19120
19121         echo $blksz
19122 }
19123
19124 test_312() { # LU-4856
19125         remote_ost_nodsh && skip "remote OST with nodsh"
19126         [ "$ost1_FSTYPE" = "zfs" ] ||
19127                 skip_env "the test only applies to zfs"
19128
19129         local max_blksz=$(do_facet ost1 \
19130                           $ZFS get -p recordsize $(facet_device ost1) |
19131                           awk '!/VALUE/{print $3}')
19132
19133         # to make life a little bit easier
19134         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19135         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19136
19137         local tf=$DIR/$tdir/$tfile
19138         touch $tf
19139         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19140
19141         # Get ZFS object id
19142         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19143         # block size change by sequential overwrite
19144         local bs
19145
19146         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19147                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19148
19149                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19150                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19151         done
19152         rm -f $tf
19153
19154         # block size change by sequential append write
19155         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19156         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19157         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19158         local count
19159
19160         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19161                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19162                         oflag=sync conv=notrunc
19163
19164                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19165                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19166                         error "blksz error, actual $blksz, " \
19167                                 "expected: 2 * $count * $PAGE_SIZE"
19168         done
19169         rm -f $tf
19170
19171         # random write
19172         touch $tf
19173         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19174         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19175
19176         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19177         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19178         [ $blksz -eq $PAGE_SIZE ] ||
19179                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19180
19181         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19182         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19183         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19184
19185         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19186         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19187         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19188 }
19189 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19190
19191 test_313() {
19192         remote_ost_nodsh && skip "remote OST with nodsh"
19193
19194         local file=$DIR/$tfile
19195
19196         rm -f $file
19197         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19198
19199         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19200         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19201         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19202                 error "write should failed"
19203         do_facet ost1 "$LCTL set_param fail_loc=0"
19204         rm -f $file
19205 }
19206 run_test 313 "io should fail after last_rcvd update fail"
19207
19208 test_314() {
19209         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19210
19211         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19212         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19213         rm -f $DIR/$tfile
19214         wait_delete_completed
19215         do_facet ost1 "$LCTL set_param fail_loc=0"
19216 }
19217 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19218
19219 test_315() { # LU-618
19220         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19221
19222         local file=$DIR/$tfile
19223         rm -f $file
19224
19225         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19226                 error "multiop file write failed"
19227         $MULTIOP $file oO_RDONLY:r4063232_c &
19228         PID=$!
19229
19230         sleep 2
19231
19232         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19233         kill -USR1 $PID
19234
19235         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19236         rm -f $file
19237 }
19238 run_test 315 "read should be accounted"
19239
19240 test_316() {
19241         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19242         large_xattr_enabled || skip_env "ea_inode feature disabled"
19243
19244         rm -rf $DIR/$tdir/d
19245         mkdir -p $DIR/$tdir/d
19246         chown nobody $DIR/$tdir/d
19247         touch $DIR/$tdir/d/file
19248
19249         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19250 }
19251 run_test 316 "lfs mv"
19252
19253 test_317() {
19254         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19255                 skip "Need MDS version at least 2.11.53"
19256         local trunc_sz
19257         local grant_blk_size
19258
19259         if [ "$(facet_fstype $facet)" == "zfs" ]; then
19260                 skip "LU-10370: no implementation for ZFS" && return
19261         fi
19262
19263         stack_trap "rm -f $DIR/$tfile" EXIT
19264         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19265                         awk '/grant_block_size:/ { print $2; exit; }')
19266         #
19267         # Create File of size 5M. Truncate it to below size's and verify
19268         # blocks count.
19269         #
19270         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19271                 error "Create file : $DIR/$tfile"
19272
19273         for trunc_sz in 2097152 4097 4000 509 0; do
19274                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19275                         error "truncate $tfile to $trunc_sz failed"
19276                 local sz=$(stat --format=%s $DIR/$tfile)
19277                 local blk=$(stat --format=%b $DIR/$tfile)
19278                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19279                                      grant_blk_size) * 8))
19280
19281                 if [[ $blk -ne $trunc_blk ]]; then
19282                         $(which stat) $DIR/$tfile
19283                         error "Expected Block $trunc_blk got $blk for $tfile"
19284                 fi
19285
19286                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19287                         error "Expected Size $trunc_sz got $sz for $tfile"
19288         done
19289
19290         #
19291         # sparse file test
19292         # Create file with a hole and write actual two blocks. Block count
19293         # must be 16.
19294         #
19295         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19296                 conv=fsync || error "Create file : $DIR/$tfile"
19297
19298         # Calculate the final truncate size.
19299         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19300
19301         #
19302         # truncate to size $trunc_sz bytes. Strip the last block
19303         # The block count must drop to 8
19304         #
19305         $TRUNCATE $DIR/$tfile $trunc_sz ||
19306                 error "truncate $tfile to $trunc_sz failed"
19307
19308         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19309         sz=$(stat --format=%s $DIR/$tfile)
19310         blk=$(stat --format=%b $DIR/$tfile)
19311
19312         if [[ $blk -ne $trunc_bsz ]]; then
19313                 $(which stat) $DIR/$tfile
19314                 error "Expected Block $trunc_bsz got $blk for $tfile"
19315         fi
19316
19317         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19318                 error "Expected Size $trunc_sz got $sz for $tfile"
19319 }
19320 run_test 317 "Verify blocks get correctly update after truncate"
19321
19322 test_318() {
19323         local old_max_active=$($LCTL get_param -n \
19324                             llite.*.max_read_ahead_async_active 2>/dev/null)
19325
19326         $LCTL set_param llite.*.max_read_ahead_async_active=256
19327         local max_active=$($LCTL get_param -n \
19328                            llite.*.max_read_ahead_async_active 2>/dev/null)
19329         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19330
19331         # currently reset to 0 is unsupported, leave it 512 for now.
19332         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19333                 error "set max_read_ahead_async_active should fail"
19334
19335         $LCTL set_param llite.*.max_read_ahead_async_active=512
19336         max_active=$($LCTL get_param -n \
19337                      llite.*.max_read_ahead_async_active 2>/dev/null)
19338         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19339
19340         # restore @max_active
19341         [ $old_max_active -ne 0 ] && $LCTL set_param \
19342                 llite.*.max_read_ahead_async_active=$old_max_active
19343
19344         local old_threshold=$($LCTL get_param -n \
19345                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19346         local max_per_file_mb=$($LCTL get_param -n \
19347                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19348
19349         local invalid=$(($max_per_file_mb + 1))
19350         $LCTL set_param \
19351                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19352                         && error "set $invalid should fail"
19353
19354         local valid=$(($invalid - 1))
19355         $LCTL set_param \
19356                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19357                         error "set $valid should succeed"
19358         local threshold=$($LCTL get_param -n \
19359                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19360         [ $threshold -eq $valid ] || error \
19361                 "expect threshold $valid got $threshold"
19362         $LCTL set_param \
19363                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19364 }
19365 run_test 318 "Verify async readahead tunables"
19366
19367 test_319() {
19368         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19369
19370         local before=$(date +%s)
19371         local evict
19372         local mdir=$DIR/$tdir
19373         local file=$mdir/xxx
19374
19375         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19376         touch $file
19377
19378 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19379         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19380         $LFS mv -m1 $file &
19381
19382         sleep 1
19383         dd if=$file of=/dev/null
19384         wait
19385         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19386           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19387
19388         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19389 }
19390 run_test 319 "lost lease lock on migrate error"
19391
19392 test_fake_rw() {
19393         local read_write=$1
19394         if [ "$read_write" = "write" ]; then
19395                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19396         elif [ "$read_write" = "read" ]; then
19397                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19398         else
19399                 error "argument error"
19400         fi
19401
19402         # turn off debug for performance testing
19403         local saved_debug=$($LCTL get_param -n debug)
19404         $LCTL set_param debug=0
19405
19406         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19407
19408         # get ost1 size - lustre-OST0000
19409         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19410         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19411         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19412
19413         if [ "$read_write" = "read" ]; then
19414                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19415         fi
19416
19417         local start_time=$(date +%s.%N)
19418         $dd_cmd bs=1M count=$blocks oflag=sync ||
19419                 error "real dd $read_write error"
19420         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19421
19422         if [ "$read_write" = "write" ]; then
19423                 rm -f $DIR/$tfile
19424         fi
19425
19426         # define OBD_FAIL_OST_FAKE_RW           0x238
19427         do_facet ost1 $LCTL set_param fail_loc=0x238
19428
19429         local start_time=$(date +%s.%N)
19430         $dd_cmd bs=1M count=$blocks oflag=sync ||
19431                 error "fake dd $read_write error"
19432         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19433
19434         if [ "$read_write" = "write" ]; then
19435                 # verify file size
19436                 cancel_lru_locks osc
19437                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19438                         error "$tfile size not $blocks MB"
19439         fi
19440         do_facet ost1 $LCTL set_param fail_loc=0
19441
19442         echo "fake $read_write $duration_fake vs. normal $read_write" \
19443                 "$duration in seconds"
19444         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19445                 error_not_in_vm "fake write is slower"
19446
19447         $LCTL set_param -n debug="$saved_debug"
19448         rm -f $DIR/$tfile
19449 }
19450 test_399a() { # LU-7655 for OST fake write
19451         remote_ost_nodsh && skip "remote OST with nodsh"
19452
19453         test_fake_rw write
19454 }
19455 run_test 399a "fake write should not be slower than normal write"
19456
19457 test_399b() { # LU-8726 for OST fake read
19458         remote_ost_nodsh && skip "remote OST with nodsh"
19459         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19460                 skip_env "ldiskfs only test"
19461         fi
19462
19463         test_fake_rw read
19464 }
19465 run_test 399b "fake read should not be slower than normal read"
19466
19467 test_400a() { # LU-1606, was conf-sanity test_74
19468         if ! which $CC > /dev/null 2>&1; then
19469                 skip_env "$CC is not installed"
19470         fi
19471
19472         local extra_flags=''
19473         local out=$TMP/$tfile
19474         local prefix=/usr/include/lustre
19475         local prog
19476
19477         if ! [[ -d $prefix ]]; then
19478                 # Assume we're running in tree and fixup the include path.
19479                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19480                 extra_flags+=" -L$LUSTRE/utils/.lib"
19481         fi
19482
19483         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19484                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19485                         error "client api broken"
19486         done
19487         rm -f $out
19488 }
19489 run_test 400a "Lustre client api program can compile and link"
19490
19491 test_400b() { # LU-1606, LU-5011
19492         local header
19493         local out=$TMP/$tfile
19494         local prefix=/usr/include/linux/lustre
19495
19496         # We use a hard coded prefix so that this test will not fail
19497         # when run in tree. There are headers in lustre/include/lustre/
19498         # that are not packaged (like lustre_idl.h) and have more
19499         # complicated include dependencies (like config.h and lnet/types.h).
19500         # Since this test about correct packaging we just skip them when
19501         # they don't exist (see below) rather than try to fixup cppflags.
19502
19503         if ! which $CC > /dev/null 2>&1; then
19504                 skip_env "$CC is not installed"
19505         fi
19506
19507         for header in $prefix/*.h; do
19508                 if ! [[ -f "$header" ]]; then
19509                         continue
19510                 fi
19511
19512                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19513                         continue # lustre_ioctl.h is internal header
19514                 fi
19515
19516                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19517                         error "cannot compile '$header'"
19518         done
19519         rm -f $out
19520 }
19521 run_test 400b "packaged headers can be compiled"
19522
19523 test_401a() { #LU-7437
19524         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19525         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19526
19527         #count the number of parameters by "list_param -R"
19528         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19529         #count the number of parameters by listing proc files
19530         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19531         echo "proc_dirs='$proc_dirs'"
19532         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19533         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19534                       sort -u | wc -l)
19535
19536         [ $params -eq $procs ] ||
19537                 error "found $params parameters vs. $procs proc files"
19538
19539         # test the list_param -D option only returns directories
19540         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19541         #count the number of parameters by listing proc directories
19542         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19543                 sort -u | wc -l)
19544
19545         [ $params -eq $procs ] ||
19546                 error "found $params parameters vs. $procs proc files"
19547 }
19548 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19549
19550 test_401b() {
19551         local save=$($LCTL get_param -n jobid_var)
19552         local tmp=testing
19553
19554         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19555                 error "no error returned when setting bad parameters"
19556
19557         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19558         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19559
19560         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19561         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19562         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19563 }
19564 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19565
19566 test_401c() {
19567         local jobid_var_old=$($LCTL get_param -n jobid_var)
19568         local jobid_var_new
19569
19570         $LCTL set_param jobid_var= &&
19571                 error "no error returned for 'set_param a='"
19572
19573         jobid_var_new=$($LCTL get_param -n jobid_var)
19574         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19575                 error "jobid_var was changed by setting without value"
19576
19577         $LCTL set_param jobid_var &&
19578                 error "no error returned for 'set_param a'"
19579
19580         jobid_var_new=$($LCTL get_param -n jobid_var)
19581         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19582                 error "jobid_var was changed by setting without value"
19583 }
19584 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19585
19586 test_401d() {
19587         local jobid_var_old=$($LCTL get_param -n jobid_var)
19588         local jobid_var_new
19589         local new_value="foo=bar"
19590
19591         $LCTL set_param jobid_var=$new_value ||
19592                 error "'set_param a=b' did not accept a value containing '='"
19593
19594         jobid_var_new=$($LCTL get_param -n jobid_var)
19595         [[ "$jobid_var_new" == "$new_value" ]] ||
19596                 error "'set_param a=b' failed on a value containing '='"
19597
19598         # Reset the jobid_var to test the other format
19599         $LCTL set_param jobid_var=$jobid_var_old
19600         jobid_var_new=$($LCTL get_param -n jobid_var)
19601         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19602                 error "failed to reset jobid_var"
19603
19604         $LCTL set_param jobid_var $new_value ||
19605                 error "'set_param a b' did not accept a value containing '='"
19606
19607         jobid_var_new=$($LCTL get_param -n jobid_var)
19608         [[ "$jobid_var_new" == "$new_value" ]] ||
19609                 error "'set_param a b' failed on a value containing '='"
19610
19611         $LCTL set_param jobid_var $jobid_var_old
19612         jobid_var_new=$($LCTL get_param -n jobid_var)
19613         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19614                 error "failed to reset jobid_var"
19615 }
19616 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19617
19618 test_402() {
19619         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19620         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19621                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19622         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19623                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19624                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19625         remote_mds_nodsh && skip "remote MDS with nodsh"
19626
19627         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19628 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19629         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19630         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19631                 echo "Touch failed - OK"
19632 }
19633 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19634
19635 test_403() {
19636         local file1=$DIR/$tfile.1
19637         local file2=$DIR/$tfile.2
19638         local tfile=$TMP/$tfile
19639
19640         rm -f $file1 $file2 $tfile
19641
19642         touch $file1
19643         ln $file1 $file2
19644
19645         # 30 sec OBD_TIMEOUT in ll_getattr()
19646         # right before populating st_nlink
19647         $LCTL set_param fail_loc=0x80001409
19648         stat -c %h $file1 > $tfile &
19649
19650         # create an alias, drop all locks and reclaim the dentry
19651         < $file2
19652         cancel_lru_locks mdc
19653         cancel_lru_locks osc
19654         sysctl -w vm.drop_caches=2
19655
19656         wait
19657
19658         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19659
19660         rm -f $tfile $file1 $file2
19661 }
19662 run_test 403 "i_nlink should not drop to zero due to aliasing"
19663
19664 test_404() { # LU-6601
19665         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19666                 skip "Need server version newer than 2.8.52"
19667         remote_mds_nodsh && skip "remote MDS with nodsh"
19668
19669         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19670                 awk '/osp .*-osc-MDT/ { print $4}')
19671
19672         local osp
19673         for osp in $mosps; do
19674                 echo "Deactivate: " $osp
19675                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19676                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19677                         awk -vp=$osp '$4 == p { print $2 }')
19678                 [ $stat = IN ] || {
19679                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19680                         error "deactivate error"
19681                 }
19682                 echo "Activate: " $osp
19683                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19684                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19685                         awk -vp=$osp '$4 == p { print $2 }')
19686                 [ $stat = UP ] || {
19687                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19688                         error "activate error"
19689                 }
19690         done
19691 }
19692 run_test 404 "validate manual {de}activated works properly for OSPs"
19693
19694 test_405() {
19695         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19696         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19697                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19698                         skip "Layout swap lock is not supported"
19699
19700         check_swap_layouts_support
19701
19702         test_mkdir $DIR/$tdir
19703         swap_lock_test -d $DIR/$tdir ||
19704                 error "One layout swap locked test failed"
19705 }
19706 run_test 405 "Various layout swap lock tests"
19707
19708 test_406() {
19709         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19710         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19711         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19712         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19713         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19714                 skip "Need MDS version at least 2.8.50"
19715
19716         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19717         local test_pool=$TESTNAME
19718
19719         if ! combined_mgs_mds ; then
19720                 mount_mgs_client
19721         fi
19722         pool_add $test_pool || error "pool_add failed"
19723         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19724                 error "pool_add_targets failed"
19725
19726         save_layout_restore_at_exit $MOUNT
19727
19728         # parent set default stripe count only, child will stripe from both
19729         # parent and fs default
19730         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19731                 error "setstripe $MOUNT failed"
19732         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19733         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19734         for i in $(seq 10); do
19735                 local f=$DIR/$tdir/$tfile.$i
19736                 touch $f || error "touch failed"
19737                 local count=$($LFS getstripe -c $f)
19738                 [ $count -eq $OSTCOUNT ] ||
19739                         error "$f stripe count $count != $OSTCOUNT"
19740                 local offset=$($LFS getstripe -i $f)
19741                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19742                 local size=$($LFS getstripe -S $f)
19743                 [ $size -eq $((def_stripe_size * 2)) ] ||
19744                         error "$f stripe size $size != $((def_stripe_size * 2))"
19745                 local pool=$($LFS getstripe -p $f)
19746                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19747         done
19748
19749         # change fs default striping, delete parent default striping, now child
19750         # will stripe from new fs default striping only
19751         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19752                 error "change $MOUNT default stripe failed"
19753         $LFS setstripe -c 0 $DIR/$tdir ||
19754                 error "delete $tdir default stripe failed"
19755         for i in $(seq 11 20); do
19756                 local f=$DIR/$tdir/$tfile.$i
19757                 touch $f || error "touch $f failed"
19758                 local count=$($LFS getstripe -c $f)
19759                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19760                 local offset=$($LFS getstripe -i $f)
19761                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19762                 local size=$($LFS getstripe -S $f)
19763                 [ $size -eq $def_stripe_size ] ||
19764                         error "$f stripe size $size != $def_stripe_size"
19765                 local pool=$($LFS getstripe -p $f)
19766                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19767         done
19768
19769         unlinkmany $DIR/$tdir/$tfile. 1 20
19770
19771         local f=$DIR/$tdir/$tfile
19772         pool_remove_all_targets $test_pool $f
19773         pool_remove $test_pool $f
19774
19775         if ! combined_mgs_mds ; then
19776                 umount_mgs_client
19777         fi
19778 }
19779 run_test 406 "DNE support fs default striping"
19780
19781 test_407() {
19782         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19783         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19784                 skip "Need MDS version at least 2.8.55"
19785         remote_mds_nodsh && skip "remote MDS with nodsh"
19786
19787         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19788                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19789         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19790                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19791         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
19792
19793         #define OBD_FAIL_DT_TXN_STOP    0x2019
19794         for idx in $(seq $MDSCOUNT); do
19795                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
19796         done
19797         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
19798         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
19799                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
19800         true
19801 }
19802 run_test 407 "transaction fail should cause operation fail"
19803
19804 test_408() {
19805         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
19806
19807         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
19808         lctl set_param fail_loc=0x8000040a
19809         # let ll_prepare_partial_page() fail
19810         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
19811
19812         rm -f $DIR/$tfile
19813
19814         # create at least 100 unused inodes so that
19815         # shrink_icache_memory(0) should not return 0
19816         touch $DIR/$tfile-{0..100}
19817         rm -f $DIR/$tfile-{0..100}
19818         sync
19819
19820         echo 2 > /proc/sys/vm/drop_caches
19821 }
19822 run_test 408 "drop_caches should not hang due to page leaks"
19823
19824 test_409()
19825 {
19826         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19827
19828         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
19829         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
19830         touch $DIR/$tdir/guard || error "(2) Fail to create"
19831
19832         local PREFIX=$(str_repeat 'A' 128)
19833         echo "Create 1K hard links start at $(date)"
19834         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19835                 error "(3) Fail to hard link"
19836
19837         echo "Links count should be right although linkEA overflow"
19838         stat $DIR/$tdir/guard || error "(4) Fail to stat"
19839         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
19840         [ $linkcount -eq 1001 ] ||
19841                 error "(5) Unexpected hard links count: $linkcount"
19842
19843         echo "List all links start at $(date)"
19844         ls -l $DIR/$tdir/foo > /dev/null ||
19845                 error "(6) Fail to list $DIR/$tdir/foo"
19846
19847         echo "Unlink hard links start at $(date)"
19848         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
19849                 error "(7) Fail to unlink"
19850         echo "Unlink hard links finished at $(date)"
19851 }
19852 run_test 409 "Large amount of cross-MDTs hard links on the same file"
19853
19854 test_410()
19855 {
19856         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
19857                 skip "Need client version at least 2.9.59"
19858
19859         # Create a file, and stat it from the kernel
19860         local testfile=$DIR/$tfile
19861         touch $testfile
19862
19863         local run_id=$RANDOM
19864         local my_ino=$(stat --format "%i" $testfile)
19865
19866         # Try to insert the module. This will always fail as the
19867         # module is designed to not be inserted.
19868         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
19869             &> /dev/null
19870
19871         # Anything but success is a test failure
19872         dmesg | grep -q \
19873             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
19874             error "no inode match"
19875 }
19876 run_test 410 "Test inode number returned from kernel thread"
19877
19878 cleanup_test411_cgroup() {
19879         trap 0
19880         rmdir "$1"
19881 }
19882
19883 test_411() {
19884         local cg_basedir=/sys/fs/cgroup/memory
19885         # LU-9966
19886         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
19887                 skip "no setup for cgroup"
19888
19889         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
19890                 error "test file creation failed"
19891         cancel_lru_locks osc
19892
19893         # Create a very small memory cgroup to force a slab allocation error
19894         local cgdir=$cg_basedir/osc_slab_alloc
19895         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
19896         trap "cleanup_test411_cgroup $cgdir" EXIT
19897         echo 2M > $cgdir/memory.kmem.limit_in_bytes
19898         echo 1M > $cgdir/memory.limit_in_bytes
19899
19900         # Should not LBUG, just be killed by oom-killer
19901         # dd will return 0 even allocation failure in some environment.
19902         # So don't check return value
19903         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
19904         cleanup_test411_cgroup $cgdir
19905
19906         return 0
19907 }
19908 run_test 411 "Slab allocation error with cgroup does not LBUG"
19909
19910 test_412() {
19911         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19912         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19913                 skip "Need server version at least 2.10.55"
19914         fi
19915
19916         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
19917                 error "mkdir failed"
19918         $LFS getdirstripe $DIR/$tdir
19919         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
19920         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
19921                 error "expect $((MDSCOUT - 1)) get $stripe_index"
19922         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
19923         [ $stripe_count -eq 2 ] ||
19924                 error "expect 2 get $stripe_count"
19925 }
19926 run_test 412 "mkdir on specific MDTs"
19927
19928 test_413a() {
19929         [ $MDSCOUNT -lt 2 ] &&
19930                 skip "We need at least 2 MDTs for this test"
19931
19932         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
19933                 skip "Need server version at least 2.10.55"
19934         fi
19935
19936         mkdir $DIR/$tdir || error "mkdir failed"
19937
19938         # find MDT that is the most full
19939         local max=$($LFS df | grep MDT |
19940                 awk 'BEGIN { a=0 }
19941                         { sub("%", "", $5)
19942                           if (0+$5 >= a)
19943                           {
19944                                 a = $5
19945                                 b = $6
19946                           }
19947                         }
19948                      END { split(b, c, ":")
19949                            sub("]", "", c[2])
19950                            print c[2]
19951                          }')
19952
19953         for i in $(seq $((MDSCOUNT - 1))); do
19954                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
19955                         error "mkdir d$i failed"
19956                 $LFS getdirstripe $DIR/$tdir/d$i
19957                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
19958                 [ $stripe_index -ne $max ] ||
19959                         error "don't expect $max"
19960         done
19961 }
19962 run_test 413a "mkdir on less full MDTs"
19963
19964 test_413b() {
19965         [ $MDSCOUNT -lt 2 ] &&
19966                 skip "We need at least 2 MDTs for this test"
19967
19968         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
19969                 skip "Need server version at least 2.12.52"
19970
19971         mkdir $DIR/$tdir || error "mkdir failed"
19972         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
19973                 error "setdirstripe failed"
19974
19975         local qos_prio_free
19976         local qos_threshold_rr
19977         local count
19978
19979         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
19980         qos_prio_free=${qos_prio_free%%%}
19981         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
19982         qos_threshold_rr=${qos_threshold_rr%%%}
19983
19984         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
19985         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
19986                 EXIT
19987
19988         echo "mkdir with roundrobin"
19989
19990         $LCTL set_param lmv.*.qos_threshold_rr=100
19991         for i in $(seq $((100 * MDSCOUNT))); do
19992                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
19993         done
19994         for i in $(seq $MDSCOUNT); do
19995                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
19996                         wc -w)
19997                 echo "$count directories created on MDT$((i - 1))"
19998                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
19999         done
20000
20001         rm -rf $DIR/$tdir/*
20002
20003         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20004
20005         local ffree
20006         local max
20007         local min
20008         local max_index
20009         local min_index
20010
20011         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20012         echo "MDT filesfree available: ${ffree[@]}"
20013         max=${ffree[0]}
20014         min=${ffree[0]}
20015         max_index=0
20016         min_index=0
20017         for ((i = 0; i < ${#ffree[@]}; i++)); do
20018                 if [[ ${ffree[i]} -gt $max ]]; then
20019                         max=${ffree[i]}
20020                         max_index=$i
20021                 fi
20022                 if [[ ${ffree[i]} -lt $min ]]; then
20023                         min=${ffree[i]}
20024                         min_index=$i
20025                 fi
20026         done
20027         echo "Min free files: MDT$min_index: $min"
20028         echo "Max free files: MDT$max_index: $max"
20029
20030         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20031         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20032
20033         # Check if we need to generate uneven MDTs
20034         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20035         local threshold=10
20036         local diff=$((max - min))
20037         local diff2=$((diff * 100 / min))
20038
20039         echo -n "Check for uneven MDTs: "
20040         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20041
20042         if [ $diff2 -gt $threshold ]; then
20043                 echo "ok"
20044                 echo "Don't need to fill MDT$min_index"
20045         else
20046                 # generate uneven MDTs, create till 25% diff
20047                 echo "no"
20048                 diff2=$((threshold - diff2))
20049                 diff=$((min * diff2 / 100))
20050                 # 50 sec per 10000 files in vm
20051                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20052                         skip "$diff files to create"
20053                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20054                 local i
20055                 local value="$(generate_string 1024)"
20056                 for i in $(seq $diff); do
20057                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20058                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20059                                 error "create f$i failed"
20060                         setfattr -n user.413b -v $value \
20061                                 $DIR/$tdir-MDT$min_index/f$i ||
20062                                 error "setfattr f$i failed"
20063                 done
20064         fi
20065
20066         min=$((100 *MDSCOUNT))
20067         max=0
20068
20069         echo "mkdir with balanced space usage"
20070         $LCTL set_param lmv.*.qos_prio_free=100
20071         for i in $(seq $((100 * MDSCOUNT))); do
20072                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20073         done
20074         for i in $(seq $MDSCOUNT); do
20075                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20076                         wc -w)
20077                 echo "$count directories created on MDT$((i - 1))"
20078                 [ $min -gt $count ] && min=$count
20079                 [ $max -lt $count ] && max=$count
20080         done
20081         [ $((max - min)) -gt $MDSCOUNT ] ||
20082                 error "subdirs shouldn't be evenly distributed"
20083
20084         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20085
20086         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20087         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20088         true
20089 }
20090 run_test 413b "mkdir with balanced space usage"
20091
20092 test_414() {
20093 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20094         $LCTL set_param fail_loc=0x80000521
20095         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20096         rm -f $DIR/$tfile
20097 }
20098 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20099
20100 test_415() {
20101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20102         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20103                 skip "Need server version at least 2.11.52"
20104
20105         # LU-11102
20106         local total
20107         local setattr_pid
20108         local start_time
20109         local end_time
20110         local duration
20111
20112         total=500
20113         # this test may be slow on ZFS
20114         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20115
20116         # though this test is designed for striped directory, let's test normal
20117         # directory too since lock is always saved as CoS lock.
20118         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20119         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20120
20121         (
20122                 while true; do
20123                         touch $DIR/$tdir
20124                 done
20125         ) &
20126         setattr_pid=$!
20127
20128         start_time=$(date +%s)
20129         for i in $(seq $total); do
20130                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20131                         > /dev/null
20132         done
20133         end_time=$(date +%s)
20134         duration=$((end_time - start_time))
20135
20136         kill -9 $setattr_pid
20137
20138         echo "rename $total files took $duration sec"
20139         [ $duration -lt 100 ] || error "rename took $duration sec"
20140 }
20141 run_test 415 "lock revoke is not missing"
20142
20143 test_416() {
20144         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20145                 skip "Need server version at least 2.11.55"
20146
20147         # define OBD_FAIL_OSD_TXN_START    0x19a
20148         do_facet mds1 lctl set_param fail_loc=0x19a
20149
20150         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20151
20152         true
20153 }
20154 run_test 416 "transaction start failure won't cause system hung"
20155
20156 cleanup_417() {
20157         trap 0
20158         do_nodes $(comma_list $(mdts_nodes)) \
20159                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20160         do_nodes $(comma_list $(mdts_nodes)) \
20161                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20162         do_nodes $(comma_list $(mdts_nodes)) \
20163                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20164 }
20165
20166 test_417() {
20167         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20168         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20169                 skip "Need MDS version at least 2.11.56"
20170
20171         trap cleanup_417 RETURN EXIT
20172
20173         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20174         do_nodes $(comma_list $(mdts_nodes)) \
20175                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20176         $LFS migrate -m 0 $DIR/$tdir.1 &&
20177                 error "migrate dir $tdir.1 should fail"
20178
20179         do_nodes $(comma_list $(mdts_nodes)) \
20180                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20181         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20182                 error "create remote dir $tdir.2 should fail"
20183
20184         do_nodes $(comma_list $(mdts_nodes)) \
20185                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20186         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20187                 error "create striped dir $tdir.3 should fail"
20188         true
20189 }
20190 run_test 417 "disable remote dir, striped dir and dir migration"
20191
20192 # Checks that the outputs of df [-i] and lfs df [-i] match
20193 #
20194 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20195 check_lfs_df() {
20196         local dir=$2
20197         local inodes
20198         local df_out
20199         local lfs_df_out
20200         local count
20201         local passed=false
20202
20203         # blocks or inodes
20204         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20205
20206         for count in {1..100}; do
20207                 cancel_lru_locks
20208                 sync; sleep 0.2
20209
20210                 # read the lines of interest
20211                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20212                         error "df $inodes $dir | tail -n +2 failed"
20213                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20214                         error "lfs df $inodes $dir | grep summary: failed"
20215
20216                 # skip first substrings of each output as they are different
20217                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20218                 # compare the two outputs
20219                 passed=true
20220                 for i in {1..5}; do
20221                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20222                 done
20223                 $passed && break
20224         done
20225
20226         if ! $passed; then
20227                 df -P $inodes $dir
20228                 echo
20229                 lfs df $inodes $dir
20230                 error "df and lfs df $1 output mismatch: "      \
20231                       "df ${inodes}: ${df_out[*]}, "            \
20232                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20233         fi
20234 }
20235
20236 test_418() {
20237         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20238
20239         local dir=$DIR/$tdir
20240         local numfiles=$((RANDOM % 4096 + 2))
20241         local numblocks=$((RANDOM % 256 + 1))
20242
20243         wait_delete_completed
20244         test_mkdir $dir
20245
20246         # check block output
20247         check_lfs_df blocks $dir
20248         # check inode output
20249         check_lfs_df inodes $dir
20250
20251         # create a single file and retest
20252         echo "Creating a single file and testing"
20253         createmany -o $dir/$tfile- 1 &>/dev/null ||
20254                 error "creating 1 file in $dir failed"
20255         check_lfs_df blocks $dir
20256         check_lfs_df inodes $dir
20257
20258         # create a random number of files
20259         echo "Creating $((numfiles - 1)) files and testing"
20260         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20261                 error "creating $((numfiles - 1)) files in $dir failed"
20262
20263         # write a random number of blocks to the first test file
20264         echo "Writing $numblocks 4K blocks and testing"
20265         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20266                 count=$numblocks &>/dev/null ||
20267                 error "dd to $dir/${tfile}-0 failed"
20268
20269         # retest
20270         check_lfs_df blocks $dir
20271         check_lfs_df inodes $dir
20272
20273         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20274                 error "unlinking $numfiles files in $dir failed"
20275 }
20276 run_test 418 "df and lfs df outputs match"
20277
20278 test_419()
20279 {
20280         local dir=$DIR/$tdir
20281
20282         mkdir -p $dir
20283         touch $dir/file
20284
20285         cancel_lru_locks mdc
20286
20287         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20288         $LCTL set_param fail_loc=0x1410
20289         cat $dir/file
20290         $LCTL set_param fail_loc=0
20291         rm -rf $dir
20292 }
20293 run_test 419 "Verify open file by name doesn't crash kernel"
20294
20295 test_420()
20296 {
20297         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20298                 skip "Need MDS version at least 2.12.53"
20299
20300         local SAVE_UMASK=$(umask)
20301         local dir=$DIR/$tdir
20302         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20303
20304         mkdir -p $dir
20305         umask 0000
20306         mkdir -m03777 $dir/testdir
20307         ls -dn $dir/testdir
20308         # Need to remove trailing '.' when SELinux is enabled
20309         local dirperms=$(ls -dn $dir/testdir |
20310                          awk '{ sub(/\.$/, "", $1); print $1}')
20311         [ $dirperms == "drwxrwsrwt" ] ||
20312                 error "incorrect perms on $dir/testdir"
20313
20314         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20315                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20316         ls -n $dir/testdir/testfile
20317         local fileperms=$(ls -n $dir/testdir/testfile |
20318                           awk '{ sub(/\.$/, "", $1); print $1}')
20319         [ $fileperms == "-rwxr-xr-x" ] ||
20320                 error "incorrect perms on $dir/testdir/testfile"
20321
20322         umask $SAVE_UMASK
20323 }
20324 run_test 420 "clear SGID bit on non-directories for non-members"
20325
20326 prep_801() {
20327         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20328         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20329                 skip "Need server version at least 2.9.55"
20330
20331         start_full_debug_logging
20332 }
20333
20334 post_801() {
20335         stop_full_debug_logging
20336 }
20337
20338 barrier_stat() {
20339         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20340                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20341                            awk '/The barrier for/ { print $7 }')
20342                 echo $st
20343         else
20344                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20345                 echo \'$st\'
20346         fi
20347 }
20348
20349 barrier_expired() {
20350         local expired
20351
20352         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20353                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20354                           awk '/will be expired/ { print $7 }')
20355         else
20356                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20357         fi
20358
20359         echo $expired
20360 }
20361
20362 test_801a() {
20363         prep_801
20364
20365         echo "Start barrier_freeze at: $(date)"
20366         #define OBD_FAIL_BARRIER_DELAY          0x2202
20367         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20368         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20369
20370         sleep 2
20371         local b_status=$(barrier_stat)
20372         echo "Got barrier status at: $(date)"
20373         [ "$b_status" = "'freezing_p1'" ] ||
20374                 error "(1) unexpected barrier status $b_status"
20375
20376         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20377         wait
20378         b_status=$(barrier_stat)
20379         [ "$b_status" = "'frozen'" ] ||
20380                 error "(2) unexpected barrier status $b_status"
20381
20382         local expired=$(barrier_expired)
20383         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20384         sleep $((expired + 3))
20385
20386         b_status=$(barrier_stat)
20387         [ "$b_status" = "'expired'" ] ||
20388                 error "(3) unexpected barrier status $b_status"
20389
20390         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20391                 error "(4) fail to freeze barrier"
20392
20393         b_status=$(barrier_stat)
20394         [ "$b_status" = "'frozen'" ] ||
20395                 error "(5) unexpected barrier status $b_status"
20396
20397         echo "Start barrier_thaw at: $(date)"
20398         #define OBD_FAIL_BARRIER_DELAY          0x2202
20399         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20400         do_facet mgs $LCTL barrier_thaw $FSNAME &
20401
20402         sleep 2
20403         b_status=$(barrier_stat)
20404         echo "Got barrier status at: $(date)"
20405         [ "$b_status" = "'thawing'" ] ||
20406                 error "(6) unexpected barrier status $b_status"
20407
20408         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20409         wait
20410         b_status=$(barrier_stat)
20411         [ "$b_status" = "'thawed'" ] ||
20412                 error "(7) unexpected barrier status $b_status"
20413
20414         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20415         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20416         do_facet mgs $LCTL barrier_freeze $FSNAME
20417
20418         b_status=$(barrier_stat)
20419         [ "$b_status" = "'failed'" ] ||
20420                 error "(8) unexpected barrier status $b_status"
20421
20422         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20423         do_facet mgs $LCTL barrier_thaw $FSNAME
20424
20425         post_801
20426 }
20427 run_test 801a "write barrier user interfaces and stat machine"
20428
20429 test_801b() {
20430         prep_801
20431
20432         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20433         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20434         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20435         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20436         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20437
20438         cancel_lru_locks mdc
20439
20440         # 180 seconds should be long enough
20441         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20442
20443         local b_status=$(barrier_stat)
20444         [ "$b_status" = "'frozen'" ] ||
20445                 error "(6) unexpected barrier status $b_status"
20446
20447         mkdir $DIR/$tdir/d0/d10 &
20448         mkdir_pid=$!
20449
20450         touch $DIR/$tdir/d1/f13 &
20451         touch_pid=$!
20452
20453         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20454         ln_pid=$!
20455
20456         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20457         mv_pid=$!
20458
20459         rm -f $DIR/$tdir/d4/f12 &
20460         rm_pid=$!
20461
20462         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20463
20464         # To guarantee taht the 'stat' is not blocked
20465         b_status=$(barrier_stat)
20466         [ "$b_status" = "'frozen'" ] ||
20467                 error "(8) unexpected barrier status $b_status"
20468
20469         # let above commands to run at background
20470         sleep 5
20471
20472         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20473         ps -p $touch_pid || error "(10) touch should be blocked"
20474         ps -p $ln_pid || error "(11) link should be blocked"
20475         ps -p $mv_pid || error "(12) rename should be blocked"
20476         ps -p $rm_pid || error "(13) unlink should be blocked"
20477
20478         b_status=$(barrier_stat)
20479         [ "$b_status" = "'frozen'" ] ||
20480                 error "(14) unexpected barrier status $b_status"
20481
20482         do_facet mgs $LCTL barrier_thaw $FSNAME
20483         b_status=$(barrier_stat)
20484         [ "$b_status" = "'thawed'" ] ||
20485                 error "(15) unexpected barrier status $b_status"
20486
20487         wait $mkdir_pid || error "(16) mkdir should succeed"
20488         wait $touch_pid || error "(17) touch should succeed"
20489         wait $ln_pid || error "(18) link should succeed"
20490         wait $mv_pid || error "(19) rename should succeed"
20491         wait $rm_pid || error "(20) unlink should succeed"
20492
20493         post_801
20494 }
20495 run_test 801b "modification will be blocked by write barrier"
20496
20497 test_801c() {
20498         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20499
20500         prep_801
20501
20502         stop mds2 || error "(1) Fail to stop mds2"
20503
20504         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20505
20506         local b_status=$(barrier_stat)
20507         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20508                 do_facet mgs $LCTL barrier_thaw $FSNAME
20509                 error "(2) unexpected barrier status $b_status"
20510         }
20511
20512         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20513                 error "(3) Fail to rescan barrier bitmap"
20514
20515         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20516
20517         b_status=$(barrier_stat)
20518         [ "$b_status" = "'frozen'" ] ||
20519                 error "(4) unexpected barrier status $b_status"
20520
20521         do_facet mgs $LCTL barrier_thaw $FSNAME
20522         b_status=$(barrier_stat)
20523         [ "$b_status" = "'thawed'" ] ||
20524                 error "(5) unexpected barrier status $b_status"
20525
20526         local devname=$(mdsdevname 2)
20527
20528         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20529
20530         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20531                 error "(7) Fail to rescan barrier bitmap"
20532
20533         post_801
20534 }
20535 run_test 801c "rescan barrier bitmap"
20536
20537 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20538 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20539 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20540
20541 cleanup_802a() {
20542         trap 0
20543
20544         stopall
20545         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20546         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20547         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20548         setupall
20549 }
20550
20551 test_802a() {
20552
20553         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20554         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20555                 skip "Need server version at least 2.9.55"
20556
20557         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
20558
20559         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20560
20561         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20562                 error "(2) Fail to copy"
20563
20564         trap cleanup_802a EXIT
20565
20566         # sync by force before remount as readonly
20567         sync; sync_all_data; sleep 3; sync_all_data
20568
20569         stopall
20570
20571         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
20572         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
20573         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
20574
20575         echo "Mount the server as read only"
20576         setupall server_only || error "(3) Fail to start servers"
20577
20578         echo "Mount client without ro should fail"
20579         mount_client $MOUNT &&
20580                 error "(4) Mount client without 'ro' should fail"
20581
20582         echo "Mount client with ro should succeed"
20583         mount_client $MOUNT ro ||
20584                 error "(5) Mount client with 'ro' should succeed"
20585
20586         echo "Modify should be refused"
20587         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20588
20589         echo "Read should be allowed"
20590         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20591                 error "(7) Read should succeed under ro mode"
20592
20593         cleanup_802a
20594 }
20595 run_test 802a "simulate readonly device"
20596
20597 test_802b() {
20598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20599         remote_mds_nodsh && skip "remote MDS with nodsh"
20600
20601         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
20602                 skip "readonly option not available"
20603
20604         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
20605
20606         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
20607                 error "(2) Fail to copy"
20608
20609         # write back all cached data before setting MDT to readonly
20610         cancel_lru_locks
20611         sync_all_data
20612
20613         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
20614         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
20615
20616         echo "Modify should be refused"
20617         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
20618
20619         echo "Read should be allowed"
20620         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
20621                 error "(7) Read should succeed under ro mode"
20622
20623         # disable readonly
20624         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
20625 }
20626 run_test 802b "be able to set MDTs to readonly"
20627
20628 test_803() {
20629         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20630         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20631                 skip "MDS needs to be newer than 2.10.54"
20632
20633         mkdir -p $DIR/$tdir
20634         # Create some objects on all MDTs to trigger related logs objects
20635         for idx in $(seq $MDSCOUNT); do
20636                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
20637                         $DIR/$tdir/dir${idx} ||
20638                         error "Fail to create $DIR/$tdir/dir${idx}"
20639         done
20640
20641         sync; sleep 3
20642         wait_delete_completed # ensure old test cleanups are finished
20643         echo "before create:"
20644         $LFS df -i $MOUNT
20645         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20646
20647         for i in {1..10}; do
20648                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
20649                         error "Fail to create $DIR/$tdir/foo$i"
20650         done
20651
20652         sync; sleep 3
20653         echo "after create:"
20654         $LFS df -i $MOUNT
20655         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20656
20657         # allow for an llog to be cleaned up during the test
20658         [ $after_used -ge $((before_used + 10 - 1)) ] ||
20659                 error "before ($before_used) + 10 > after ($after_used)"
20660
20661         for i in {1..10}; do
20662                 rm -rf $DIR/$tdir/foo$i ||
20663                         error "Fail to remove $DIR/$tdir/foo$i"
20664         done
20665
20666         sleep 3 # avoid MDT return cached statfs
20667         wait_delete_completed
20668         echo "after unlink:"
20669         $LFS df -i $MOUNT
20670         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
20671
20672         # allow for an llog to be created during the test
20673         [ $after_used -le $((before_used + 1)) ] ||
20674                 error "after ($after_used) > before ($before_used) + 1"
20675 }
20676 run_test 803 "verify agent object for remote object"
20677
20678 test_804() {
20679         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20680         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
20681                 skip "MDS needs to be newer than 2.10.54"
20682         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
20683
20684         mkdir -p $DIR/$tdir
20685         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
20686                 error "Fail to create $DIR/$tdir/dir0"
20687
20688         local fid=$($LFS path2fid $DIR/$tdir/dir0)
20689         local dev=$(mdsdevname 2)
20690
20691         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20692                 grep ${fid} || error "NOT found agent entry for dir0"
20693
20694         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
20695                 error "Fail to create $DIR/$tdir/dir1"
20696
20697         touch $DIR/$tdir/dir1/foo0 ||
20698                 error "Fail to create $DIR/$tdir/dir1/foo0"
20699         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
20700         local rc=0
20701
20702         for idx in $(seq $MDSCOUNT); do
20703                 dev=$(mdsdevname $idx)
20704                 do_facet mds${idx} \
20705                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20706                         grep ${fid} && rc=$idx
20707         done
20708
20709         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
20710                 error "Fail to rename foo0 to foo1"
20711         if [ $rc -eq 0 ]; then
20712                 for idx in $(seq $MDSCOUNT); do
20713                         dev=$(mdsdevname $idx)
20714                         do_facet mds${idx} \
20715                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20716                         grep ${fid} && rc=$idx
20717                 done
20718         fi
20719
20720         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
20721                 error "Fail to rename foo1 to foo2"
20722         if [ $rc -eq 0 ]; then
20723                 for idx in $(seq $MDSCOUNT); do
20724                         dev=$(mdsdevname $idx)
20725                         do_facet mds${idx} \
20726                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
20727                         grep ${fid} && rc=$idx
20728                 done
20729         fi
20730
20731         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
20732
20733         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
20734                 error "Fail to link to $DIR/$tdir/dir1/foo2"
20735         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
20736                 error "Fail to rename foo2 to foo0"
20737         unlink $DIR/$tdir/dir1/foo0 ||
20738                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
20739         rm -rf $DIR/$tdir/dir0 ||
20740                 error "Fail to rm $DIR/$tdir/dir0"
20741
20742         for idx in $(seq $MDSCOUNT); do
20743                 dev=$(mdsdevname $idx)
20744                 rc=0
20745
20746                 stop mds${idx}
20747                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
20748                         rc=$?
20749                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
20750                         error "mount mds$idx failed"
20751                 df $MOUNT > /dev/null 2>&1
20752
20753                 # e2fsck should not return error
20754                 [ $rc -eq 0 ] ||
20755                         error "e2fsck detected error on MDT${idx}: rc=$rc"
20756         done
20757 }
20758 run_test 804 "verify agent entry for remote entry"
20759
20760 cleanup_805() {
20761         do_facet $SINGLEMDS zfs set quota=$old $fsset
20762         unlinkmany $DIR/$tdir/f- 1000000
20763         trap 0
20764 }
20765
20766 test_805() {
20767         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
20768         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
20769         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
20770                 skip "netfree not implemented before 0.7"
20771         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
20772                 skip "Need MDS version at least 2.10.57"
20773
20774         local fsset
20775         local freekb
20776         local usedkb
20777         local old
20778         local quota
20779         local pref="osd-zfs.lustre-MDT0000."
20780
20781         # limit available space on MDS dataset to meet nospace issue
20782         # quickly. then ZFS 0.7.2 can use reserved space if asked
20783         # properly (using netfree flag in osd_declare_destroy()
20784         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
20785         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
20786                 gawk '{print $3}')
20787         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
20788         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
20789         let "usedkb=usedkb-freekb"
20790         let "freekb=freekb/2"
20791         if let "freekb > 5000"; then
20792                 let "freekb=5000"
20793         fi
20794         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
20795         trap cleanup_805 EXIT
20796         mkdir $DIR/$tdir
20797         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
20798         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
20799         rm -rf $DIR/$tdir || error "not able to remove"
20800         do_facet $SINGLEMDS zfs set quota=$old $fsset
20801         trap 0
20802 }
20803 run_test 805 "ZFS can remove from full fs"
20804
20805 # Size-on-MDS test
20806 check_lsom_data()
20807 {
20808         local file=$1
20809         local size=$($LFS getsom -s $file)
20810         local expect=$(stat -c %s $file)
20811
20812         [[ $size == $expect ]] ||
20813                 error "$file expected size: $expect, got: $size"
20814
20815         local blocks=$($LFS getsom -b $file)
20816         expect=$(stat -c %b $file)
20817         [[ $blocks == $expect ]] ||
20818                 error "$file expected blocks: $expect, got: $blocks"
20819 }
20820
20821 check_lsom_size()
20822 {
20823         local size=$($LFS getsom -s $1)
20824         local expect=$2
20825
20826         [[ $size == $expect ]] ||
20827                 error "$file expected size: $expect, got: $size"
20828 }
20829
20830 test_806() {
20831         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20832                 skip "Need MDS version at least 2.11.52"
20833
20834         local bs=1048576
20835
20836         touch $DIR/$tfile || error "touch $tfile failed"
20837
20838         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20839         save_lustre_params client "llite.*.xattr_cache" > $save
20840         lctl set_param llite.*.xattr_cache=0
20841         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20842
20843         # single-threaded write
20844         echo "Test SOM for single-threaded write"
20845         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
20846                 error "write $tfile failed"
20847         check_lsom_size $DIR/$tfile $bs
20848
20849         local num=32
20850         local size=$(($num * $bs))
20851         local offset=0
20852         local i
20853
20854         echo "Test SOM for single client multi-threaded($num) write"
20855         $TRUNCATE $DIR/$tfile 0
20856         for ((i = 0; i < $num; i++)); do
20857                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20858                 local pids[$i]=$!
20859                 offset=$((offset + $bs))
20860         done
20861         for (( i=0; i < $num; i++ )); do
20862                 wait ${pids[$i]}
20863         done
20864         check_lsom_size $DIR/$tfile $size
20865
20866         $TRUNCATE $DIR/$tfile 0
20867         for ((i = 0; i < $num; i++)); do
20868                 offset=$((offset - $bs))
20869                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20870                 local pids[$i]=$!
20871         done
20872         for (( i=0; i < $num; i++ )); do
20873                 wait ${pids[$i]}
20874         done
20875         check_lsom_size $DIR/$tfile $size
20876
20877         # multi-client wirtes
20878         num=$(get_node_count ${CLIENTS//,/ })
20879         size=$(($num * $bs))
20880         offset=0
20881         i=0
20882
20883         echo "Test SOM for multi-client ($num) writes"
20884         $TRUNCATE $DIR/$tfile 0
20885         for client in ${CLIENTS//,/ }; do
20886                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20887                 local pids[$i]=$!
20888                 i=$((i + 1))
20889                 offset=$((offset + $bs))
20890         done
20891         for (( i=0; i < $num; i++ )); do
20892                 wait ${pids[$i]}
20893         done
20894         check_lsom_size $DIR/$tfile $offset
20895
20896         i=0
20897         $TRUNCATE $DIR/$tfile 0
20898         for client in ${CLIENTS//,/ }; do
20899                 offset=$((offset - $bs))
20900                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20901                 local pids[$i]=$!
20902                 i=$((i + 1))
20903         done
20904         for (( i=0; i < $num; i++ )); do
20905                 wait ${pids[$i]}
20906         done
20907         check_lsom_size $DIR/$tfile $size
20908
20909         # verify truncate
20910         echo "Test SOM for truncate"
20911         $TRUNCATE $DIR/$tfile 1048576
20912         check_lsom_size $DIR/$tfile 1048576
20913         $TRUNCATE $DIR/$tfile 1234
20914         check_lsom_size $DIR/$tfile 1234
20915
20916         # verify SOM blocks count
20917         echo "Verify SOM block count"
20918         $TRUNCATE $DIR/$tfile 0
20919         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
20920                 error "failed to write file $tfile"
20921         check_lsom_data $DIR/$tfile
20922 }
20923 run_test 806 "Verify Lazy Size on MDS"
20924
20925 test_807() {
20926         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20927         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
20928                 skip "Need MDS version at least 2.11.52"
20929
20930         # Registration step
20931         changelog_register || error "changelog_register failed"
20932         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
20933         changelog_users $SINGLEMDS | grep -q $cl_user ||
20934                 error "User $cl_user not found in changelog_users"
20935
20936         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
20937         save_lustre_params client "llite.*.xattr_cache" > $save
20938         lctl set_param llite.*.xattr_cache=0
20939         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
20940
20941         rm -rf $DIR/$tdir || error "rm $tdir failed"
20942         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
20943         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
20944         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
20945         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
20946                 error "truncate $tdir/trunc failed"
20947
20948         local bs=1048576
20949         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
20950                 error "write $tfile failed"
20951
20952         # multi-client wirtes
20953         local num=$(get_node_count ${CLIENTS//,/ })
20954         local offset=0
20955         local i=0
20956
20957         echo "Test SOM for multi-client ($num) writes"
20958         touch $DIR/$tfile || error "touch $tfile failed"
20959         $TRUNCATE $DIR/$tfile 0
20960         for client in ${CLIENTS//,/ }; do
20961                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
20962                 local pids[$i]=$!
20963                 i=$((i + 1))
20964                 offset=$((offset + $bs))
20965         done
20966         for (( i=0; i < $num; i++ )); do
20967                 wait ${pids[$i]}
20968         done
20969
20970         sleep 5
20971         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
20972         check_lsom_data $DIR/$tdir/trunc
20973         check_lsom_data $DIR/$tdir/single_dd
20974         check_lsom_data $DIR/$tfile
20975
20976         rm -rf $DIR/$tdir
20977         # Deregistration step
20978         changelog_deregister || error "changelog_deregister failed"
20979 }
20980 run_test 807 "verify LSOM syncing tool"
20981
20982 check_som_nologged()
20983 {
20984         local lines=$($LFS changelog $FSNAME-MDT0000 |
20985                 grep 'x=trusted.som' | wc -l)
20986         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
20987 }
20988
20989 test_808() {
20990         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
20991                 skip "Need MDS version at least 2.11.55"
20992
20993         # Registration step
20994         changelog_register || error "changelog_register failed"
20995
20996         touch $DIR/$tfile || error "touch $tfile failed"
20997         check_som_nologged
20998
20999         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21000                 error "write $tfile failed"
21001         check_som_nologged
21002
21003         $TRUNCATE $DIR/$tfile 1234
21004         check_som_nologged
21005
21006         $TRUNCATE $DIR/$tfile 1048576
21007         check_som_nologged
21008
21009         # Deregistration step
21010         changelog_deregister || error "changelog_deregister failed"
21011 }
21012 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21013
21014 check_som_nodata()
21015 {
21016         $LFS getsom $1
21017         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21018 }
21019
21020 test_809() {
21021         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21022                 skip "Need MDS version at least 2.11.56"
21023
21024         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21025                 error "failed to create DoM-only file $DIR/$tfile"
21026         touch $DIR/$tfile || error "touch $tfile failed"
21027         check_som_nodata $DIR/$tfile
21028
21029         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21030                 error "write $tfile failed"
21031         check_som_nodata $DIR/$tfile
21032
21033         $TRUNCATE $DIR/$tfile 1234
21034         check_som_nodata $DIR/$tfile
21035
21036         $TRUNCATE $DIR/$tfile 4097
21037         check_som_nodata $DIR/$file
21038 }
21039 run_test 809 "Verify no SOM xattr store for DoM-only files"
21040
21041 test_810() {
21042         local ORIG
21043         local CSUM
21044
21045         # t10 seem to dislike partial pages
21046         lctl set_param osc.*.checksum_type=adler
21047         lctl set_param fail_loc=0x411
21048         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21049         ORIG=$(md5sum $DIR/$tfile)
21050         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21051         CSUM=$(md5sum $DIR/$tfile)
21052         set_checksum_type adler
21053         if [ "$ORIG" != "$CSUM" ]; then
21054                 error "$ORIG != $CSUM"
21055         fi
21056 }
21057 run_test 810 "partial page writes on ZFS (LU-11663)"
21058
21059 test_811() {
21060         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21061                 skip "Need MDS version at least 2.11.56"
21062
21063         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21064         do_facet mds1 $LCTL set_param fail_loc=0x165
21065         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21066
21067         stop mds1
21068         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21069
21070         sleep 5
21071         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21072                 error "MDD orphan cleanup thread not quit"
21073 }
21074 run_test 811 "orphan name stub can be cleaned up in startup"
21075
21076 test_812() {
21077         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21078                 skip "OST < 2.12.51 doesn't support this fail_loc"
21079         [ "$SHARED_KEY" = true ] &&
21080                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21081
21082         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21083         # ensure ost1 is connected
21084         stat $DIR/$tfile >/dev/null || error "can't stat"
21085         wait_osc_import_state client ost1 FULL
21086         # no locks, no reqs to let the connection idle
21087         cancel_lru_locks osc
21088
21089         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21090 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21091         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21092         wait_osc_import_state client ost1 CONNECTING
21093         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21094
21095         stat $DIR/$tfile >/dev/null || error "can't stat file"
21096 }
21097 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21098
21099 test_813() {
21100         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21101         [ -z "$file_heat_sav" ] && skip "no file heat support"
21102
21103         local readsample
21104         local writesample
21105         local readbyte
21106         local writebyte
21107         local readsample1
21108         local writesample1
21109         local readbyte1
21110         local writebyte1
21111
21112         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21113         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21114
21115         $LCTL set_param -n llite.*.file_heat=1
21116         echo "Turn on file heat"
21117         echo "Period second: $period_second, Decay percentage: $decay_pct"
21118
21119         echo "QQQQ" > $DIR/$tfile
21120         echo "QQQQ" > $DIR/$tfile
21121         echo "QQQQ" > $DIR/$tfile
21122         cat $DIR/$tfile > /dev/null
21123         cat $DIR/$tfile > /dev/null
21124         cat $DIR/$tfile > /dev/null
21125         cat $DIR/$tfile > /dev/null
21126
21127         local out=$($LFS heat_get $DIR/$tfile)
21128
21129         $LFS heat_get $DIR/$tfile
21130         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21131         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21132         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21133         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21134
21135         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21136         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21137         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21138         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21139
21140         sleep $((period_second + 3))
21141         echo "Sleep $((period_second + 3)) seconds..."
21142         # The recursion formula to calculate the heat of the file f is as
21143         # follow:
21144         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21145         # Where Hi is the heat value in the period between time points i*I and
21146         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21147         # to the weight of Ci.
21148         out=$($LFS heat_get $DIR/$tfile)
21149         $LFS heat_get $DIR/$tfile
21150         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21151         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21152         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21153         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21154
21155         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21156                 error "read sample ($readsample) is wrong"
21157         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21158                 error "write sample ($writesample) is wrong"
21159         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21160                 error "read bytes ($readbyte) is wrong"
21161         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21162                 error "write bytes ($writebyte) is wrong"
21163
21164         echo "QQQQ" > $DIR/$tfile
21165         echo "QQQQ" > $DIR/$tfile
21166         echo "QQQQ" > $DIR/$tfile
21167         cat $DIR/$tfile > /dev/null
21168         cat $DIR/$tfile > /dev/null
21169         cat $DIR/$tfile > /dev/null
21170         cat $DIR/$tfile > /dev/null
21171
21172         sleep $((period_second + 3))
21173         echo "Sleep $((period_second + 3)) seconds..."
21174
21175         out=$($LFS heat_get $DIR/$tfile)
21176         $LFS heat_get $DIR/$tfile
21177         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21178         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21179         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21180         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21181
21182         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21183                 4 * $decay_pct) / 100") -eq 1 ] ||
21184                 error "read sample ($readsample1) is wrong"
21185         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21186                 3 * $decay_pct) / 100") -eq 1 ] ||
21187                 error "write sample ($writesample1) is wrong"
21188         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21189                 20 * $decay_pct) / 100") -eq 1 ] ||
21190                 error "read bytes ($readbyte1) is wrong"
21191         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21192                 15 * $decay_pct) / 100") -eq 1 ] ||
21193                 error "write bytes ($writebyte1) is wrong"
21194
21195         echo "Turn off file heat for the file $DIR/$tfile"
21196         $LFS heat_set -o $DIR/$tfile
21197
21198         echo "QQQQ" > $DIR/$tfile
21199         echo "QQQQ" > $DIR/$tfile
21200         echo "QQQQ" > $DIR/$tfile
21201         cat $DIR/$tfile > /dev/null
21202         cat $DIR/$tfile > /dev/null
21203         cat $DIR/$tfile > /dev/null
21204         cat $DIR/$tfile > /dev/null
21205
21206         out=$($LFS heat_get $DIR/$tfile)
21207         $LFS heat_get $DIR/$tfile
21208         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21209         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21210         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21211         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21212
21213         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21214         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21215         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21216         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21217
21218         echo "Trun on file heat for the file $DIR/$tfile"
21219         $LFS heat_set -O $DIR/$tfile
21220
21221         echo "QQQQ" > $DIR/$tfile
21222         echo "QQQQ" > $DIR/$tfile
21223         echo "QQQQ" > $DIR/$tfile
21224         cat $DIR/$tfile > /dev/null
21225         cat $DIR/$tfile > /dev/null
21226         cat $DIR/$tfile > /dev/null
21227         cat $DIR/$tfile > /dev/null
21228
21229         out=$($LFS heat_get $DIR/$tfile)
21230         $LFS heat_get $DIR/$tfile
21231         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21232         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21233         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21234         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21235
21236         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21237         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21238         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21239         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21240
21241         $LFS heat_set -c $DIR/$tfile
21242         $LCTL set_param -n llite.*.file_heat=0
21243         echo "Turn off file heat support for the Lustre filesystem"
21244
21245         echo "QQQQ" > $DIR/$tfile
21246         echo "QQQQ" > $DIR/$tfile
21247         echo "QQQQ" > $DIR/$tfile
21248         cat $DIR/$tfile > /dev/null
21249         cat $DIR/$tfile > /dev/null
21250         cat $DIR/$tfile > /dev/null
21251         cat $DIR/$tfile > /dev/null
21252
21253         out=$($LFS heat_get $DIR/$tfile)
21254         $LFS heat_get $DIR/$tfile
21255         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21256         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21257         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21258         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21259
21260         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21261         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21262         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21263         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21264
21265         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21266         rm -f $DIR/$tfile
21267 }
21268 run_test 813 "File heat verfication"
21269
21270 test_814()
21271 {
21272         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21273         echo -n y >> $DIR/$tfile
21274         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21275         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21276 }
21277 run_test 814 "sparse cp works as expected (LU-12361)"
21278
21279 test_815()
21280 {
21281         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21282         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21283 }
21284 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21285
21286 test_816() {
21287         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21288         # ensure ost1 is connected
21289         stat $DIR/$tfile >/dev/null || error "can't stat"
21290         wait_osc_import_state client ost1 FULL
21291         # no locks, no reqs to let the connection idle
21292         cancel_lru_locks osc
21293         lru_resize_disable osc
21294         local before
21295         local now
21296         before=$($LCTL get_param -n \
21297                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21298
21299         wait_osc_import_state client ost1 IDLE
21300         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21301         now=$($LCTL get_param -n \
21302               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21303         [ $before == $now ] || error "lru_size changed $before != $now"
21304 }
21305 run_test 816 "do not reset lru_resize on idle reconnect"
21306
21307 #
21308 # tests that do cleanup/setup should be run at the end
21309 #
21310
21311 test_900() {
21312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21313         local ls
21314
21315         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21316         $LCTL set_param fail_loc=0x903
21317
21318         cancel_lru_locks MGC
21319
21320         FAIL_ON_ERROR=true cleanup
21321         FAIL_ON_ERROR=true setup
21322 }
21323 run_test 900 "umount should not race with any mgc requeue thread"
21324
21325 complete $SECONDS
21326 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21327 check_and_cleanup_lustre
21328 if [ "$I_MOUNTED" != "yes" ]; then
21329         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21330 fi
21331 exit_status