Whamcloud - gitweb
LU-12394 llite: Fix extents_stats
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f "
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         # bug number:    LU-11596
55         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
56         # bug number:    LU-11671 LU-11667 LU-11729 LU-4398
57         ALWAYS_EXCEPT+=" 45       317      810       817"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test: LU-1957
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  180"
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1746 # if the OST isn't full anymore.
1747 reset_enospc() {
1748         local OSTIDX=${1:-""}
1749
1750         local list=$(comma_list $(osts_nodes))
1751         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1752
1753         do_nodes $list lctl set_param fail_loc=0
1754         sync    # initiate all OST_DESTROYs from MDS to OST
1755         sleep_maxage
1756 }
1757
1758 exhaust_precreations() {
1759         local OSTIDX=$1
1760         local FAILLOC=$2
1761         local FAILIDX=${3:-$OSTIDX}
1762         local ofacet=ost$((OSTIDX + 1))
1763
1764         test_mkdir -p -c1 $DIR/$tdir
1765         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1766         local mfacet=mds$((mdtidx + 1))
1767         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1768
1769         local OST=$(ostname_from_index $OSTIDX)
1770
1771         # on the mdt's osc
1772         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1773         local last_id=$(do_facet $mfacet lctl get_param -n \
1774                         osp.$mdtosc_proc1.prealloc_last_id)
1775         local next_id=$(do_facet $mfacet lctl get_param -n \
1776                         osp.$mdtosc_proc1.prealloc_next_id)
1777
1778         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1779         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1780
1781         test_mkdir -p $DIR/$tdir/${OST}
1782         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1783 #define OBD_FAIL_OST_ENOSPC              0x215
1784         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1785         echo "Creating to objid $last_id on ost $OST..."
1786         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1787         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1788         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1789         sleep_maxage
1790 }
1791
1792 exhaust_all_precreations() {
1793         local i
1794         for (( i=0; i < OSTCOUNT; i++ )) ; do
1795                 exhaust_precreations $i $1 -1
1796         done
1797 }
1798
1799 test_27n() {
1800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1802         remote_mds_nodsh && skip "remote MDS with nodsh"
1803         remote_ost_nodsh && skip "remote OST with nodsh"
1804
1805         reset_enospc
1806         rm -f $DIR/$tdir/$tfile
1807         exhaust_precreations 0 0x80000215
1808         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1809         touch $DIR/$tdir/$tfile || error "touch failed"
1810         $LFS getstripe $DIR/$tdir/$tfile
1811         reset_enospc
1812 }
1813 run_test 27n "create file with some full OSTs"
1814
1815 test_27o() {
1816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1818         remote_mds_nodsh && skip "remote MDS with nodsh"
1819         remote_ost_nodsh && skip "remote OST with nodsh"
1820
1821         reset_enospc
1822         rm -f $DIR/$tdir/$tfile
1823         exhaust_all_precreations 0x215
1824
1825         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1826
1827         reset_enospc
1828         rm -rf $DIR/$tdir/*
1829 }
1830 run_test 27o "create file with all full OSTs (should error)"
1831
1832 test_27p() {
1833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836         remote_ost_nodsh && skip "remote OST with nodsh"
1837
1838         reset_enospc
1839         rm -f $DIR/$tdir/$tfile
1840         test_mkdir $DIR/$tdir
1841
1842         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1843         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1844         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1845
1846         exhaust_precreations 0 0x80000215
1847         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1848         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1849         $LFS getstripe $DIR/$tdir/$tfile
1850
1851         reset_enospc
1852 }
1853 run_test 27p "append to a truncated file with some full OSTs"
1854
1855 test_27q() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863
1864         test_mkdir $DIR/$tdir
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1867                 error "truncate $DIR/$tdir/$tfile failed"
1868         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1869
1870         exhaust_all_precreations 0x215
1871
1872         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1873         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1874
1875         reset_enospc
1876 }
1877 run_test 27q "append to truncated file with all OSTs full (should error)"
1878
1879 test_27r() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_precreations 0 0x80000215
1888
1889         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1890
1891         reset_enospc
1892 }
1893 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1894
1895 test_27s() { # bug 10725
1896         test_mkdir $DIR/$tdir
1897         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1898         local stripe_count=0
1899         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1900         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1901                 error "stripe width >= 2^32 succeeded" || true
1902
1903 }
1904 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1905
1906 test_27t() { # bug 10864
1907         WDIR=$(pwd)
1908         WLFS=$(which lfs)
1909         cd $DIR
1910         touch $tfile
1911         $WLFS getstripe $tfile
1912         cd $WDIR
1913 }
1914 run_test 27t "check that utils parse path correctly"
1915
1916 test_27u() { # bug 4900
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919
1920         local index
1921         local list=$(comma_list $(mdts_nodes))
1922
1923 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1924         do_nodes $list $LCTL set_param fail_loc=0x139
1925         test_mkdir -p $DIR/$tdir
1926         trap simple_cleanup_common EXIT
1927         createmany -o $DIR/$tdir/t- 1000
1928         do_nodes $list $LCTL set_param fail_loc=0
1929
1930         TLOG=$TMP/$tfile.getstripe
1931         $LFS getstripe $DIR/$tdir > $TLOG
1932         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1933         unlinkmany $DIR/$tdir/t- 1000
1934         trap 0
1935         [[ $OBJS -gt 0 ]] &&
1936                 error "$OBJS objects created on OST-0. See $TLOG" ||
1937                 rm -f $TLOG
1938 }
1939 run_test 27u "skip object creation on OSC w/o objects"
1940
1941 test_27v() { # bug 4900
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         exhaust_all_precreations 0x215
1948         reset_enospc
1949
1950         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1951
1952         touch $DIR/$tdir/$tfile
1953         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1954         # all except ost1
1955         for (( i=1; i < OSTCOUNT; i++ )); do
1956                 do_facet ost$i lctl set_param fail_loc=0x705
1957         done
1958         local START=`date +%s`
1959         createmany -o $DIR/$tdir/$tfile 32
1960
1961         local FINISH=`date +%s`
1962         local TIMEOUT=`lctl get_param -n timeout`
1963         local PROCESS=$((FINISH - START))
1964         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1965                error "$FINISH - $START >= $TIMEOUT / 2"
1966         sleep $((TIMEOUT / 2 - PROCESS))
1967         reset_enospc
1968 }
1969 run_test 27v "skip object creation on slow OST"
1970
1971 test_27w() { # bug 10997
1972         test_mkdir $DIR/$tdir
1973         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1974         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1975                 error "stripe size $size != 65536" || true
1976         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1977                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1978 }
1979 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1980
1981 test_27wa() {
1982         [[ $OSTCOUNT -lt 2 ]] &&
1983                 skip_env "skipping multiple stripe count/offset test"
1984
1985         test_mkdir $DIR/$tdir
1986         for i in $(seq 1 $OSTCOUNT); do
1987                 offset=$((i - 1))
1988                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1989                         error "setstripe -c $i -i $offset failed"
1990                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1991                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1992                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1993                 [ $index -ne $offset ] &&
1994                         error "stripe offset $index != $offset" || true
1995         done
1996 }
1997 run_test 27wa "check $LFS setstripe -c -i options"
1998
1999 test_27x() {
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003
2004         OFFSET=$(($OSTCOUNT - 1))
2005         OSTIDX=0
2006         local OST=$(ostname_from_index $OSTIDX)
2007
2008         test_mkdir $DIR/$tdir
2009         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2010         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2011         sleep_maxage
2012         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2013         for i in $(seq 0 $OFFSET); do
2014                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2015                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2016                 error "OST0 was degraded but new created file still use it"
2017         done
2018         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2019 }
2020 run_test 27x "create files while OST0 is degraded"
2021
2022 test_27y() {
2023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2024         remote_mds_nodsh && skip "remote MDS with nodsh"
2025         remote_ost_nodsh && skip "remote OST with nodsh"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027
2028         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2029         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2030                 osp.$mdtosc.prealloc_last_id)
2031         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2032                 osp.$mdtosc.prealloc_next_id)
2033         local fcount=$((last_id - next_id))
2034         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2035         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2036
2037         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2038                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2039         local OST_DEACTIVE_IDX=-1
2040         local OSC
2041         local OSTIDX
2042         local OST
2043
2044         for OSC in $MDS_OSCS; do
2045                 OST=$(osc_to_ost $OSC)
2046                 OSTIDX=$(index_from_ostuuid $OST)
2047                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2048                         OST_DEACTIVE_IDX=$OSTIDX
2049                 fi
2050                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2051                         echo $OSC "is Deactivated:"
2052                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2053                 fi
2054         done
2055
2056         OSTIDX=$(index_from_ostuuid $OST)
2057         test_mkdir $DIR/$tdir
2058         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2059
2060         for OSC in $MDS_OSCS; do
2061                 OST=$(osc_to_ost $OSC)
2062                 OSTIDX=$(index_from_ostuuid $OST)
2063                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2064                         echo $OST "is degraded:"
2065                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2066                                                 obdfilter.$OST.degraded=1
2067                 fi
2068         done
2069
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $fcount
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is recovered from degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=0
2080                 else
2081                         do_facet $SINGLEMDS lctl --device %$OSC activate
2082                 fi
2083         done
2084
2085         # all osp devices get activated, hence -1 stripe count restored
2086         local stripe_count=0
2087
2088         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2089         # devices get activated.
2090         sleep_maxage
2091         $LFS setstripe -c -1 $DIR/$tfile
2092         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2093         rm -f $DIR/$tfile
2094         [ $stripe_count -ne $OSTCOUNT ] &&
2095                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2096         return 0
2097 }
2098 run_test 27y "create files while OST0 is degraded and the rest inactive"
2099
2100 check_seq_oid()
2101 {
2102         log "check file $1"
2103
2104         lmm_count=$($LFS getstripe -c $1)
2105         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2106         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2107
2108         local old_ifs="$IFS"
2109         IFS=$'[:]'
2110         fid=($($LFS path2fid $1))
2111         IFS="$old_ifs"
2112
2113         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2114         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2115
2116         # compare lmm_seq and lu_fid->f_seq
2117         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2118         # compare lmm_object_id and lu_fid->oid
2119         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2120
2121         # check the trusted.fid attribute of the OST objects of the file
2122         local have_obdidx=false
2123         local stripe_nr=0
2124         $LFS getstripe $1 | while read obdidx oid hex seq; do
2125                 # skip lines up to and including "obdidx"
2126                 [ -z "$obdidx" ] && break
2127                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2128                 $have_obdidx || continue
2129
2130                 local ost=$((obdidx + 1))
2131                 local dev=$(ostdevname $ost)
2132                 local oid_hex
2133
2134                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2135
2136                 seq=$(echo $seq | sed -e "s/^0x//g")
2137                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2138                         oid_hex=$(echo $oid)
2139                 else
2140                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2141                 fi
2142                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2143
2144                 local ff=""
2145                 #
2146                 # Don't unmount/remount the OSTs if we don't need to do that.
2147                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2148                 # update too, until that use mount/ll_decode_filter_fid/mount.
2149                 # Re-enable when debugfs will understand new filter_fid.
2150                 #
2151                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2152                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2153                                 $dev 2>/dev/null" | grep "parent=")
2154                 fi
2155                 if [ -z "$ff" ]; then
2156                         stop ost$ost
2157                         mount_fstype ost$ost
2158                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2159                                 $(facet_mntpt ost$ost)/$obj_file)
2160                         unmount_fstype ost$ost
2161                         start ost$ost $dev $OST_MOUNT_OPTS
2162                         clients_up
2163                 fi
2164
2165                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2166
2167                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2168
2169                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2170                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2171                 #
2172                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2173                 #       stripe_size=1048576 component_id=1 component_start=0 \
2174                 #       component_end=33554432
2175                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2176                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2177                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2178                 local ff_pstripe
2179                 if grep -q 'stripe=' <<<$ff; then
2180                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2181                 else
2182                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2183                         # into f_ver in this case.  See comment on ff_parent.
2184                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2185                 fi
2186
2187                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2188                 [ $ff_pseq = $lmm_seq ] ||
2189                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2190                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2191                 [ $ff_poid = $lmm_oid ] ||
2192                         error "FF parent OID $ff_poid != $lmm_oid"
2193                 (($ff_pstripe == $stripe_nr)) ||
2194                         error "FF stripe $ff_pstripe != $stripe_nr"
2195
2196                 stripe_nr=$((stripe_nr + 1))
2197                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2198                         continue
2199                 if grep -q 'stripe_count=' <<<$ff; then
2200                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2201                                             -e 's/ .*//' <<<$ff)
2202                         [ $lmm_count = $ff_scnt ] ||
2203                                 error "FF stripe count $lmm_count != $ff_scnt"
2204                 fi
2205         done
2206 }
2207
2208 test_27z() {
2209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2210         remote_ost_nodsh && skip "remote OST with nodsh"
2211
2212         test_mkdir $DIR/$tdir
2213         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2214                 { error "setstripe -c -1 failed"; return 1; }
2215         # We need to send a write to every object to get parent FID info set.
2216         # This _should_ also work for setattr, but does not currently.
2217         # touch $DIR/$tdir/$tfile-1 ||
2218         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2219                 { error "dd $tfile-1 failed"; return 2; }
2220         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2221                 { error "setstripe -c -1 failed"; return 3; }
2222         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2223                 { error "dd $tfile-2 failed"; return 4; }
2224
2225         # make sure write RPCs have been sent to OSTs
2226         sync; sleep 5; sync
2227
2228         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2229         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2230 }
2231 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2232
2233 test_27A() { # b=19102
2234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2235
2236         save_layout_restore_at_exit $MOUNT
2237         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2238         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2239                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2240         local default_size=$($LFS getstripe -S $MOUNT)
2241         local default_offset=$($LFS getstripe -i $MOUNT)
2242         local dsize=$(do_facet $SINGLEMDS \
2243                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2244         [ $default_size -eq $dsize ] ||
2245                 error "stripe size $default_size != $dsize"
2246         [ $default_offset -eq -1 ] ||
2247                 error "stripe offset $default_offset != -1"
2248 }
2249 run_test 27A "check filesystem-wide default LOV EA values"
2250
2251 test_27B() { # LU-2523
2252         test_mkdir $DIR/$tdir
2253         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2254         touch $DIR/$tdir/f0
2255         # open f1 with O_LOV_DELAY_CREATE
2256         # rename f0 onto f1
2257         # call setstripe ioctl on open file descriptor for f1
2258         # close
2259         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2260                 $DIR/$tdir/f0
2261
2262         rm -f $DIR/$tdir/f1
2263         # open f1 with O_LOV_DELAY_CREATE
2264         # unlink f1
2265         # call setstripe ioctl on open file descriptor for f1
2266         # close
2267         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2268
2269         # Allow multiop to fail in imitation of NFS's busted semantics.
2270         true
2271 }
2272 run_test 27B "call setstripe on open unlinked file/rename victim"
2273
2274 # 27C family tests full striping and overstriping
2275 test_27Ca() { #LU-2871
2276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2277
2278         declare -a ost_idx
2279         local index
2280         local found
2281         local i
2282         local j
2283
2284         test_mkdir $DIR/$tdir
2285         cd $DIR/$tdir
2286         for i in $(seq 0 $((OSTCOUNT - 1))); do
2287                 # set stripe across all OSTs starting from OST$i
2288                 $LFS setstripe -i $i -c -1 $tfile$i
2289                 # get striping information
2290                 ost_idx=($($LFS getstripe $tfile$i |
2291                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2292                 echo ${ost_idx[@]}
2293
2294                 # check the layout
2295                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2296                         error "${#ost_idx[@]} != $OSTCOUNT"
2297
2298                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2299                         found=0
2300                         for j in $(echo ${ost_idx[@]}); do
2301                                 if [ $index -eq $j ]; then
2302                                         found=1
2303                                         break
2304                                 fi
2305                         done
2306                         [ $found = 1 ] ||
2307                                 error "Can not find $index in ${ost_idx[@]}"
2308                 done
2309         done
2310 }
2311 run_test 27Ca "check full striping across all OSTs"
2312
2313 test_27Cb() {
2314         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2315                 skip "server does not support overstriping"
2316         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2317                 skip_env "too many osts, skipping"
2318
2319         test_mkdir -p $DIR/$tdir
2320         local setcount=$(($OSTCOUNT * 2))
2321         [ $setcount -ge 160 ] || large_xattr_enabled ||
2322                 skip_env "ea_inode feature disabled"
2323
2324         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2325                 error "setstripe failed"
2326
2327         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2328         [ $count -eq $setcount ] ||
2329                 error "stripe count $count, should be $setcount"
2330
2331         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2332                 error "overstriped should be set in pattern"
2333
2334         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2335                 error "dd failed"
2336 }
2337 run_test 27Cb "more stripes than OSTs with -C"
2338
2339 test_27Cc() {
2340         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2341                 skip "server does not support overstriping"
2342         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2343
2344         test_mkdir -p $DIR/$tdir
2345         local setcount=$(($OSTCOUNT - 1))
2346
2347         [ $setcount -ge 160 ] || large_xattr_enabled ||
2348                 skip_env "ea_inode feature disabled"
2349
2350         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2351                 error "setstripe failed"
2352
2353         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2354         [ $count -eq $setcount ] ||
2355                 error "stripe count $count, should be $setcount"
2356
2357         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2358                 error "overstriped should not be set in pattern"
2359
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2361                 error "dd failed"
2362 }
2363 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2364
2365 test_27Cd() {
2366         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2367                 skip "server does not support overstriping"
2368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2369         large_xattr_enabled || skip_env "ea_inode feature disabled"
2370
2371         test_mkdir -p $DIR/$tdir
2372         local setcount=$LOV_MAX_STRIPE_COUNT
2373
2374         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2375                 error "setstripe failed"
2376
2377         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2378         [ $count -eq $setcount ] ||
2379                 error "stripe count $count, should be $setcount"
2380
2381         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2382                 error "overstriped should be set in pattern"
2383
2384         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2385                 error "dd failed"
2386
2387         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2388 }
2389 run_test 27Cd "test maximum stripe count"
2390
2391 test_27Ce() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         test_mkdir -p $DIR/$tdir
2395
2396         pool_add $TESTNAME || error "Pool creation failed"
2397         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2398
2399         local setcount=8
2400
2401         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2402                 error "setstripe failed"
2403
2404         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2405         [ $count -eq $setcount ] ||
2406                 error "stripe count $count, should be $setcount"
2407
2408         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2409                 error "overstriped should be set in pattern"
2410
2411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2412                 error "dd failed"
2413
2414         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2415 }
2416 run_test 27Ce "test pool with overstriping"
2417
2418 test_27Cf() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2422                 skip_env "too many osts, skipping"
2423
2424         test_mkdir -p $DIR/$tdir
2425
2426         local setcount=$(($OSTCOUNT * 2))
2427         [ $setcount -ge 160 ] || large_xattr_enabled ||
2428                 skip_env "ea_inode feature disabled"
2429
2430         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2431                 error "setstripe failed"
2432
2433         echo 1 > $DIR/$tdir/$tfile
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444
2445         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2446 }
2447 run_test 27Cf "test default inheritance with overstriping"
2448
2449 test_27D() {
2450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2452         remote_mds_nodsh && skip "remote MDS with nodsh"
2453
2454         local POOL=${POOL:-testpool}
2455         local first_ost=0
2456         local last_ost=$(($OSTCOUNT - 1))
2457         local ost_step=1
2458         local ost_list=$(seq $first_ost $ost_step $last_ost)
2459         local ost_range="$first_ost $last_ost $ost_step"
2460
2461         if ! combined_mgs_mds ; then
2462                 mount_mgs_client
2463         fi
2464
2465         test_mkdir $DIR/$tdir
2466         pool_add $POOL || error "pool_add failed"
2467         pool_add_targets $POOL $ost_range || error "pool_add_targets failed"
2468
2469         local skip27D
2470         [ $MDS1_VERSION -lt $(version_code 2.8.55) ] &&
2471                 skip27D+="-s 29"
2472         [ $MDS1_VERSION -lt $(version_code 2.9.55) ] ||
2473                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2474                         skip27D+=" -s 30,31"
2475         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code $SEL_VER) ] &&
2476                 skip27D+="-s 32"
2477         [[ ! $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ||
2478           $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2479                 skip27D+=" -s 32,33"
2480         llapi_layout_test -d$DIR/$tdir -p$POOL -o$OSTCOUNT $skip27D ||
2481                 error "llapi_layout_test failed"
2482
2483         destroy_test_pools || error "destroy test pools failed"
2484
2485         if ! combined_mgs_mds ; then
2486                 umount_mgs_client
2487         fi
2488 }
2489 run_test 27D "validate llapi_layout API"
2490
2491 # Verify that default_easize is increased from its initial value after
2492 # accessing a widely striped file.
2493 test_27E() {
2494         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2495         [ $CLIENT_VERSION -lt $(version_code 2.5.57) ] &&
2496                 skip "client does not have LU-3338 fix"
2497
2498         # 72 bytes is the minimum space required to store striping
2499         # information for a file striped across one OST:
2500         # (sizeof(struct lov_user_md_v3) +
2501         #  sizeof(struct lov_user_ost_data_v1))
2502         local min_easize=72
2503         $LCTL set_param -n llite.*.default_easize $min_easize ||
2504                 error "lctl set_param failed"
2505         local easize=$($LCTL get_param -n llite.*.default_easize)
2506
2507         [ $easize -eq $min_easize ] ||
2508                 error "failed to set default_easize"
2509
2510         $LFS setstripe -c $OSTCOUNT $DIR/$tfile ||
2511                 error "setstripe failed"
2512         # In order to ensure stat() call actually talks to MDS we need to
2513         # do something drastic to this file to shake off all lock, e.g.
2514         # rename it (kills lookup lock forcing cache cleaning)
2515         mv $DIR/$tfile $DIR/${tfile}-1
2516         ls -l $DIR/${tfile}-1
2517         rm $DIR/${tfile}-1
2518
2519         easize=$($LCTL get_param -n llite.*.default_easize)
2520
2521         [ $easize -gt $min_easize ] ||
2522                 error "default_easize not updated"
2523 }
2524 run_test 27E "check that default extended attribute size properly increases"
2525
2526 test_27F() { # LU-5346/LU-7975
2527         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2528         [[ $OSTCOUNT -lt 2 ]] && skip "needs >= 2 OSTs"
2529         [[ $MDS1_VERSION -lt $(version_code 2.8.51) ]] &&
2530                 skip "Need MDS version at least 2.8.51"
2531         remote_ost_nodsh && skip "remote OST with nodsh"
2532
2533         test_mkdir $DIR/$tdir
2534         rm -f $DIR/$tdir/f0
2535         $LFS setstripe -c 2 $DIR/$tdir
2536
2537         # stop all OSTs to reproduce situation for LU-7975 ticket
2538         for num in $(seq $OSTCOUNT); do
2539                 stop ost$num
2540         done
2541
2542         # open/create f0 with O_LOV_DELAY_CREATE
2543         # truncate f0 to a non-0 size
2544         # close
2545         multiop $DIR/$tdir/f0 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T1050000c
2546
2547         $CHECKSTAT -s 1050000 $DIR/$tdir/f0 || error "checkstat failed"
2548         # open/write it again to force delayed layout creation
2549         cat /etc/hosts > $DIR/$tdir/f0 &
2550         catpid=$!
2551
2552         # restart OSTs
2553         for num in $(seq $OSTCOUNT); do
2554                 start ost$num $(ostdevname $num) $OST_MOUNT_OPTS ||
2555                         error "ost$num failed to start"
2556         done
2557
2558         wait $catpid || error "cat failed"
2559
2560         cmp /etc/hosts $DIR/$tdir/f0 || error "cmp failed"
2561         [[ $($LFS getstripe -c $DIR/$tdir/f0) == 2 ]] ||
2562                 error "wrong stripecount"
2563
2564 }
2565 run_test 27F "Client resend delayed layout creation with non-zero size"
2566
2567 test_27G() { #LU-10629
2568         [ $MDS1_VERSION -lt $(version_code 2.11.51) ] &&
2569                 skip "Need MDS version at least 2.11.51"
2570         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2571         remote_mds_nodsh && skip "remote MDS with nodsh"
2572         local POOL=${POOL:-testpool}
2573         local ostrange="0 0 1"
2574
2575         test_mkdir $DIR/$tdir
2576         pool_add $POOL || error "pool_add failed"
2577         pool_add_targets $POOL $ostrange || error "pool_add_targets failed"
2578         $LFS setstripe -p $POOL $DIR/$tdir
2579
2580         local pool=$($LFS getstripe -p $DIR/$tdir)
2581
2582         [ "$pool" = "$POOL" ] || error "Striping failed got '$pool' not '$POOL'"
2583
2584         $LFS setstripe -d $DIR/$tdir
2585
2586         pool=$($LFS getstripe -p $DIR/$tdir)
2587
2588         rmdir $DIR/$tdir
2589
2590         [ -z "$pool" ] || error "'$pool' is not empty"
2591 }
2592 run_test 27G "Clear OST pool from stripe"
2593
2594 test_27H() {
2595         [[ $MDS1_VERSION -le $(version_code 2.11.54) ]] &&
2596                 skip "Need MDS version newer than 2.11.54"
2597         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
2598         test_mkdir $DIR/$tdir
2599         $LFS setstripe -o 0 -o 2 $DIR/$tdir || error "setstripe failed"
2600         touch $DIR/$tdir/$tfile
2601         $LFS getstripe -c $DIR/$tdir/$tfile
2602         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
2603                 error "two-stripe file doesn't have two stripes"
2604
2605         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
2606         $LFS getstripe -y $DIR/$tdir/$tfile
2607         (( $($LFS getstripe -y $DIR/$tdir/$tfile |
2608              egrep -c "l_ost_idx: [02]$") == "2" )) ||
2609                 error "expected l_ost_idx: [02]$ not matched"
2610
2611         # make sure ost list has been cleared
2612         local stripesize=$($LFS getstripe -S $DIR/$tdir)
2613         $LFS setstripe -S $((stripesize * 4)) -i 1 \
2614                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
2615         touch $DIR/$tdir/f3
2616         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
2617 }
2618 run_test 27H "Set specific OSTs stripe"
2619
2620 test_27I() {
2621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2622         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2623         local pool=$TESTNAME
2624         local ostrange="1 1 1"
2625
2626         save_layout_restore_at_exit $MOUNT
2627         $LFS setstripe -c 2 -i 0 $MOUNT
2628         pool_add $pool || error "pool_add failed"
2629         pool_add_targets $pool $ostrange || "pool_add_targets failed"
2630         test_mkdir $DIR/$tdir
2631         $LFS setstripe -p $pool $DIR/$tdir
2632         $MULTIOP $DIR/$tdir/$tfile Oc || error "multiop failed"
2633         $LFS getstripe $DIR/$tdir/$tfile
2634 }
2635 run_test 27I "check that root dir striping does not break parent dir one"
2636
2637 test_27J() {
2638         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.51) ]] &&
2639                 skip "Need MDS version newer than 2.12.51"
2640
2641         test_mkdir $DIR/$tdir
2642         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2643         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2644
2645         # create foreign file (raw way)
2646         create_foreign_file -f $DIR/$tdir/$tfile -x "${uuid1}@${uuid2}" \
2647                 -t 1 -F 0xda08 || error "create_foreign_file failed"
2648
2649         # verify foreign file (raw way)
2650         parse_foreign_file -f $DIR/$tdir/$tfile |
2651                 grep "lov_foreign_magic: 0x0BD70BD0" ||
2652                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign magic"
2653         parse_foreign_file -f $DIR/$tdir/$tfile | grep "lov_xattr_size: 89" ||
2654                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2655         parse_foreign_file -f $DIR/$tdir/$tfile |
2656                 grep "lov_foreign_size: 73" ||
2657                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign size"
2658         parse_foreign_file -f $DIR/$tdir/$tfile |
2659                 grep "lov_foreign_type: 1" ||
2660                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign type"
2661         parse_foreign_file -f $DIR/$tdir/$tfile |
2662                 grep "lov_foreign_flags: 0x0000DA08" ||
2663                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign flags"
2664         local lov=$(parse_foreign_file -f $DIR/$tdir/$tfile |
2665                 grep "lov_foreign_value: 0x" |
2666                 sed -e 's/lov_foreign_value: 0x//')
2667         local lov2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160)
2668         [[ $lov = ${lov2// /} ]] ||
2669                 error "$DIR/$tdir/$tfile: invalid LOV EA foreign value"
2670
2671         # create foreign file (lfs + API)
2672         $LFS setstripe --foreign=daos --flags 0xda08 \
2673                 -x "${uuid1}@${uuid2}" $DIR/$tdir/${tfile}2 ||
2674                 error "$DIR/$tdir/${tfile}2: create failed"
2675
2676         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2677                 grep "lfm_magic:.*0x0BD70BD0" ||
2678                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign magic"
2679         # lfm_length is LOV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2680         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_length:.*73" ||
2681                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign size"
2682         $LFS getstripe -v $DIR/$tdir/${tfile}2 | grep "lfm_type:.*daos" ||
2683                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign type"
2684         $LFS getstripe -v $DIR/$tdir/${tfile}2 |
2685                 grep "lfm_flags:.*0x0000DA08" ||
2686                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign flags"
2687         $LFS getstripe $DIR/$tdir/${tfile}2 |
2688                 grep "lfm_value:.*${uuid1}@${uuid2}" ||
2689                 error "$DIR/$tdir/${tfile}2: invalid LOV EA foreign value"
2690
2691         # modify striping should fail
2692         $LFS setstripe -c 2 $DIR/$tdir/$tfile &&
2693                 error "$DIR/$tdir/$tfile: setstripe should fail"
2694         $LFS setstripe -c 2 $DIR/$tdir/${tfile}2 &&
2695                 error "$DIR/$tdir/${tfile}2: setstripe should fail"
2696
2697         # R/W should fail
2698         cat $DIR/$tdir/$tfile && error "$DIR/$tdir/$tfile: read should fail"
2699         cat $DIR/$tdir/${tfile}2 &&
2700                 error "$DIR/$tdir/${tfile}2: read should fail"
2701         cat /etc/passwd > $DIR/$tdir/$tfile &&
2702                 error "$DIR/$tdir/$tfile: write should fail"
2703         cat /etc/passwd > $DIR/$tdir/${tfile}2 &&
2704                 error "$DIR/$tdir/${tfile}2: write should fail"
2705
2706         # chmod should work
2707         chmod 222 $DIR/$tdir/$tfile ||
2708                 error "$DIR/$tdir/$tfile: chmod failed"
2709         chmod 222 $DIR/$tdir/${tfile}2 ||
2710                 error "$DIR/$tdir/${tfile}2: chmod failed"
2711
2712         # chown should work
2713         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tfile ||
2714                 error "$DIR/$tdir/$tfile: chown failed"
2715         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tfile}2 ||
2716                 error "$DIR/$tdir/${tfile}2: chown failed"
2717
2718         # rename should work
2719         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}.new ||
2720                 error "$DIR/$tdir/$tfile: rename of foreign file has failed"
2721         mv $DIR/$tdir/${tfile}2 $DIR/$tdir/${tfile}2.new ||
2722                 error "$DIR/$tdir/${tfile}2: rename of foreign file has failed"
2723
2724         #remove foreign file
2725         rm $DIR/$tdir/${tfile}.new ||
2726                 error "$DIR/$tdir/${tfile}.new: remove of foreign file has failed"
2727         rm $DIR/$tdir/${tfile}2.new ||
2728                 error "$DIR/$tdir/${tfile}2.new: remove of foreign file has failed"
2729 }
2730 run_test 27J "basic ops on file with foreign LOV"
2731
2732 test_27K() {
2733         [[ $(lustre_version_code $SINGLEMDS) -le $(version_code 2.12.49) ]] &&
2734                 skip "Need MDS version newer than 2.12.49"
2735
2736         test_mkdir $DIR/$tdir
2737         local uuid1=$(cat /proc/sys/kernel/random/uuid)
2738         local uuid2=$(cat /proc/sys/kernel/random/uuid)
2739
2740         # create foreign dir (raw way)
2741         create_foreign_dir -d $DIR/$tdir/$tdir -x "${uuid1}@${uuid2}" -t 1 ||
2742                 error "create_foreign_dir FAILED"
2743
2744         # verify foreign dir (raw way)
2745         parse_foreign_dir -d $DIR/$tdir/$tdir |
2746                 grep "lmv_foreign_magic:.*0xcd50cd0" ||
2747                 error "$DIR/$tdir/$tfile: invalid LMV EA magic"
2748         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_xattr_size:.*89$" ||
2749                 error "$DIR/$tdir/$tdir: invalid LMV EA size"
2750         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_type: 1$" ||
2751                 error "$DIR/$tdir/$tdir: invalid LMV EA type"
2752         parse_foreign_dir -d $DIR/$tdir/$tdir | grep "lmv_foreign_flags: 0$" ||
2753                 error "$DIR/$tdir/$tdir: invalid LMV EA flags"
2754         local lmv=$(parse_foreign_dir -d $DIR/$tdir/$tdir |
2755                 grep "lmv_foreign_value: 0x" |
2756                 sed 's/lmv_foreign_value: 0x//')
2757         local lmv2=$(echo -n "${uuid1}@${uuid2}" | od -A n -t x1 -w160 |
2758                 sed 's/ //g')
2759         [[ $lmv == $lmv2 ]] || error "$DIR/$tdir/$tdir: invalid LMV EA value"
2760
2761         # create foreign dir (lfs + API)
2762         $LFS mkdir --foreign=daos --xattr="${uuid1}@${uuid2}" --flags=0xda05 \
2763                 $DIR/$tdir/${tdir}2 ||
2764                 error "$DIR/$tdir/${tdir}2: create failed"
2765
2766         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2767                 grep "lfm_magic:.*0x0CD50CD0" ||
2768                 error "$DIR/$tdir/${tdir}2: invalid LMV EA magic"
2769         # lfm_length is LMV EA size - sizeof(lfm_magic) - sizeof(lfm_length)
2770         # - sizeof(lfm_type) - sizeof(lfm_flags)
2771         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_length:.*73" ||
2772                 error "$DIR/$tdir/${tdir}2: invalid LMV EA size"
2773         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 | grep "lfm_type:.*daos" ||
2774                 error "$DIR/$tdir/${tdir}2: invalid LMV EA type"
2775         $LFS getdirstripe -v $DIR/$tdir/${tdir}2 |
2776                 grep "lfm_flags:.*0x0000DA05" ||
2777                 error "$DIR/$tdir/${tdir}2: invalid LMV EA flags"
2778         $LFS getdirstripe $DIR/$tdir/${tdir}2 |
2779                 grep "lfm_value.*${uuid1}@${uuid2}" ||
2780                 error "$DIR/$tdir/${tdir}2: invalid LMV EA value"
2781
2782         # file create in dir should fail
2783         touch $DIR/$tdir/$tdir/$tfile && "$DIR/$tdir: file create should fail"
2784         touch $DIR/$tdir/${tdir}2/$tfile &&
2785                 "$DIR/${tdir}2: file create should fail"
2786
2787         # chmod should work
2788         chmod 777 $DIR/$tdir/$tdir ||
2789                 error "$DIR/$tdir: chmod failed"
2790         chmod 777 $DIR/$tdir/${tdir}2 ||
2791                 error "$DIR/${tdir}2: chmod failed"
2792
2793         # chown should work
2794         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/$tdir ||
2795                 error "$DIR/$tdir: chown failed"
2796         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/${tdir}2 ||
2797                 error "$DIR/${tdir}2: chown failed"
2798
2799         # rename should work
2800         mv $DIR/$tdir/$tdir $DIR/$tdir/${tdir}.new ||
2801                 error "$DIR/$tdir/$tdir: rename of foreign dir has failed"
2802         mv $DIR/$tdir/${tdir}2 $DIR/$tdir/${tdir}2.new ||
2803                 error "$DIR/$tdir/${tdir}2: rename of foreign dir has failed"
2804
2805         #remove foreign dir
2806         rmdir $DIR/$tdir/${tdir}.new ||
2807                 error "$DIR/$tdir/${tdir}.new: remove of foreign dir has failed"
2808         rmdir $DIR/$tdir/${tdir}2.new ||
2809                 error "$DIR/$tdir/${tdir}2.new: remove of foreign dir has failed"
2810 }
2811 run_test 27K "basic ops on dir with foreign LMV"
2812
2813 test_27L() {
2814         remote_mds_nodsh && skip "remote MDS with nodsh"
2815
2816         local POOL=${POOL:-$TESTNAME}
2817
2818         if ! combined_mgs_mds ; then
2819                 mount_mgs_client
2820                 trap umount_mgs_client EXIT
2821         fi
2822
2823         pool_add $POOL || error "pool_add failed"
2824
2825         lfs pool_list $MOUNT | grep -Fx "${FSNAME}.${POOL}" ||
2826                  error "pool_list does not contain ${FSNAME}.${POOL}:" \
2827                        "$(lfs pool_list $MOUNT | grep -F "${POOL}")"
2828 }
2829 run_test 27L "lfs pool_list gives correct pool name"
2830
2831 # createtest also checks that device nodes are created and
2832 # then visible correctly (#2091)
2833 test_28() { # bug 2091
2834         test_mkdir $DIR/d28
2835         $CREATETEST $DIR/d28/ct || error "createtest failed"
2836 }
2837 run_test 28 "create/mknod/mkdir with bad file types ============"
2838
2839 test_29() {
2840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2841
2842         sync; sleep 1; sync # flush out any dirty pages from previous tests
2843         cancel_lru_locks
2844         test_mkdir $DIR/d29
2845         touch $DIR/d29/foo
2846         log 'first d29'
2847         ls -l $DIR/d29
2848
2849         declare -i LOCKCOUNTORIG=0
2850         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2851                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2852         done
2853         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2854
2855         declare -i LOCKUNUSEDCOUNTORIG=0
2856         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2857                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2858         done
2859
2860         log 'second d29'
2861         ls -l $DIR/d29
2862         log 'done'
2863
2864         declare -i LOCKCOUNTCURRENT=0
2865         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2866                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
2867         done
2868
2869         declare -i LOCKUNUSEDCOUNTCURRENT=0
2870         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2871                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
2872         done
2873
2874         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
2875                 $LCTL set_param -n ldlm.dump_namespaces ""
2876                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
2877                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2878                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2879                 return 2
2880         fi
2881         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
2882                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
2883                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
2884                 log "dumped log to $TMP/test_29.dk (bug 5793)"
2885                 return 3
2886         fi
2887 }
2888 run_test 29 "IT_GETATTR regression  ============================"
2889
2890 test_30a() { # was test_30
2891         cp $(which ls) $DIR || cp /bin/ls $DIR
2892         $DIR/ls / || error "Can't execute binary from lustre"
2893         rm $DIR/ls
2894 }
2895 run_test 30a "execute binary from Lustre (execve) =============="
2896
2897 test_30b() {
2898         cp `which ls` $DIR || cp /bin/ls $DIR
2899         chmod go+rx $DIR/ls
2900         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
2901         rm $DIR/ls
2902 }
2903 run_test 30b "execute binary from Lustre as non-root ==========="
2904
2905 test_30c() { # b=22376
2906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2907
2908         cp `which ls` $DIR || cp /bin/ls $DIR
2909         chmod a-rw $DIR/ls
2910         cancel_lru_locks mdc
2911         cancel_lru_locks osc
2912         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
2913         rm -f $DIR/ls
2914 }
2915 run_test 30c "execute binary from Lustre without read perms ===="
2916
2917 test_31a() {
2918         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
2919         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
2920 }
2921 run_test 31a "open-unlink file =================================="
2922
2923 test_31b() {
2924         touch $DIR/f31 || error "touch $DIR/f31 failed"
2925         ln $DIR/f31 $DIR/f31b || error "ln failed"
2926         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
2927         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
2928 }
2929 run_test 31b "unlink file with multiple links while open ======="
2930
2931 test_31c() {
2932         touch $DIR/f31 || error "touch $DIR/f31 failed"
2933         ln $DIR/f31 $DIR/f31c || error "ln failed"
2934         multiop_bg_pause $DIR/f31 O_uc ||
2935                 error "multiop_bg_pause for $DIR/f31 failed"
2936         MULTIPID=$!
2937         $MULTIOP $DIR/f31c Ouc
2938         kill -USR1 $MULTIPID
2939         wait $MULTIPID
2940 }
2941 run_test 31c "open-unlink file with multiple links ============="
2942
2943 test_31d() {
2944         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
2945         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
2946 }
2947 run_test 31d "remove of open directory ========================="
2948
2949 test_31e() { # bug 2904
2950         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
2951 }
2952 run_test 31e "remove of open non-empty directory ==============="
2953
2954 test_31f() { # bug 4554
2955         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2956
2957         set -vx
2958         test_mkdir $DIR/d31f
2959         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2960         cp /etc/hosts $DIR/d31f
2961         ls -l $DIR/d31f
2962         $LFS getstripe $DIR/d31f/hosts
2963         multiop_bg_pause $DIR/d31f D_c || return 1
2964         MULTIPID=$!
2965
2966         rm -rv $DIR/d31f || error "first of $DIR/d31f"
2967         test_mkdir $DIR/d31f
2968         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
2969         cp /etc/hosts $DIR/d31f
2970         ls -l $DIR/d31f
2971         $LFS getstripe $DIR/d31f/hosts
2972         multiop_bg_pause $DIR/d31f D_c || return 1
2973         MULTIPID2=$!
2974
2975         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
2976         wait $MULTIPID || error "first opendir $MULTIPID failed"
2977
2978         sleep 6
2979
2980         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
2981         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
2982         set +vx
2983 }
2984 run_test 31f "remove of open directory with open-unlink file ==="
2985
2986 test_31g() {
2987         echo "-- cross directory link --"
2988         test_mkdir -c1 $DIR/${tdir}ga
2989         test_mkdir -c1 $DIR/${tdir}gb
2990         touch $DIR/${tdir}ga/f
2991         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
2992         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
2993         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
2994         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
2995         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
2996 }
2997 run_test 31g "cross directory link==============="
2998
2999 test_31h() {
3000         echo "-- cross directory link --"
3001         test_mkdir -c1 $DIR/${tdir}
3002         test_mkdir -c1 $DIR/${tdir}/dir
3003         touch $DIR/${tdir}/f
3004         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3005         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3006         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3007         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3008         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3009 }
3010 run_test 31h "cross directory link under child==============="
3011
3012 test_31i() {
3013         echo "-- cross directory link --"
3014         test_mkdir -c1 $DIR/$tdir
3015         test_mkdir -c1 $DIR/$tdir/dir
3016         touch $DIR/$tdir/dir/f
3017         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3018         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3019         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3020         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3021         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3022 }
3023 run_test 31i "cross directory link under parent==============="
3024
3025 test_31j() {
3026         test_mkdir -c1 -p $DIR/$tdir
3027         test_mkdir -c1 -p $DIR/$tdir/dir1
3028         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3029         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3030         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3031         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3032         return 0
3033 }
3034 run_test 31j "link for directory==============="
3035
3036 test_31k() {
3037         test_mkdir -c1 -p $DIR/$tdir
3038         touch $DIR/$tdir/s
3039         touch $DIR/$tdir/exist
3040         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3041         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3042         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3043         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3044         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3045         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3046         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3047         return 0
3048 }
3049 run_test 31k "link to file: the same, non-existing, dir==============="
3050
3051 test_31m() {
3052         mkdir $DIR/d31m
3053         touch $DIR/d31m/s
3054         mkdir $DIR/d31m2
3055         touch $DIR/d31m2/exist
3056         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3057         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3058         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3059         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3060         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3061         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3062         return 0
3063 }
3064 run_test 31m "link to file: the same, non-existing, dir==============="
3065
3066 test_31n() {
3067         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3068         nlink=$(stat --format=%h $DIR/$tfile)
3069         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3070         local fd=$(free_fd)
3071         local cmd="exec $fd<$DIR/$tfile"
3072         eval $cmd
3073         cmd="exec $fd<&-"
3074         trap "eval $cmd" EXIT
3075         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3076         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3077         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3078         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3079         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3080         eval $cmd
3081 }
3082 run_test 31n "check link count of unlinked file"
3083
3084 link_one() {
3085         local tempfile=$(mktemp $1_XXXXXX)
3086         mlink $tempfile $1 2> /dev/null &&
3087                 echo "$BASHPID: link $tempfile to $1 succeeded"
3088         munlink $tempfile
3089 }
3090
3091 test_31o() { # LU-2901
3092         test_mkdir $DIR/$tdir
3093         for LOOP in $(seq 100); do
3094                 rm -f $DIR/$tdir/$tfile*
3095                 for THREAD in $(seq 8); do
3096                         link_one $DIR/$tdir/$tfile.$LOOP &
3097                 done
3098                 wait
3099                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3100                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3101                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3102                         break || true
3103         done
3104 }
3105 run_test 31o "duplicate hard links with same filename"
3106
3107 test_31p() {
3108         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3109
3110         test_mkdir $DIR/$tdir
3111         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3112         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3113
3114         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3115                 error "open unlink test1 failed"
3116         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3117                 error "open unlink test2 failed"
3118
3119         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3120                 error "test1 still exists"
3121         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3122                 error "test2 still exists"
3123 }
3124 run_test 31p "remove of open striped directory"
3125
3126 cleanup_test32_mount() {
3127         local rc=0
3128         trap 0
3129         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3130         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3131         losetup -d $loopdev || true
3132         rm -rf $DIR/$tdir
3133         return $rc
3134 }
3135
3136 test_32a() {
3137         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3138
3139         echo "== more mountpoints and symlinks ================="
3140         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3141         trap cleanup_test32_mount EXIT
3142         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3143         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3144                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3145         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3146                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3147         cleanup_test32_mount
3148 }
3149 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3150
3151 test_32b() {
3152         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3153
3154         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3155         trap cleanup_test32_mount EXIT
3156         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3157         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3158                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3159         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3160                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3161         cleanup_test32_mount
3162 }
3163 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3164
3165 test_32c() {
3166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3167
3168         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3169         trap cleanup_test32_mount EXIT
3170         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3171         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3172                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3173         test_mkdir -p $DIR/$tdir/d2/test_dir
3174         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3175                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3176         cleanup_test32_mount
3177 }
3178 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3179
3180 test_32d() {
3181         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3182
3183         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3184         trap cleanup_test32_mount EXIT
3185         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3186         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3187                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3188         test_mkdir -p $DIR/$tdir/d2/test_dir
3189         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3190                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3191         cleanup_test32_mount
3192 }
3193 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3194
3195 test_32e() {
3196         rm -fr $DIR/$tdir
3197         test_mkdir -p $DIR/$tdir/tmp
3198         local tmp_dir=$DIR/$tdir/tmp
3199         ln -s $DIR/$tdir $tmp_dir/symlink11
3200         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3201         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3202         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3203 }
3204 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3205
3206 test_32f() {
3207         rm -fr $DIR/$tdir
3208         test_mkdir -p $DIR/$tdir/tmp
3209         local tmp_dir=$DIR/$tdir/tmp
3210         ln -s $DIR/$tdir $tmp_dir/symlink11
3211         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3212         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3213         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3214 }
3215 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3216
3217 test_32g() {
3218         local tmp_dir=$DIR/$tdir/tmp
3219         test_mkdir -p $tmp_dir
3220         test_mkdir $DIR/${tdir}2
3221         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3222         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3223         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3224         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3225         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3226         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3227 }
3228 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3229
3230 test_32h() {
3231         rm -fr $DIR/$tdir $DIR/${tdir}2
3232         tmp_dir=$DIR/$tdir/tmp
3233         test_mkdir -p $tmp_dir
3234         test_mkdir $DIR/${tdir}2
3235         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3236         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3237         ls $tmp_dir/symlink12 || error "listing symlink12"
3238         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3239 }
3240 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3241
3242 test_32i() {
3243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3244
3245         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3246         trap cleanup_test32_mount EXIT
3247         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3248         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3249                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3250         touch $DIR/$tdir/test_file
3251         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3252                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3253         cleanup_test32_mount
3254 }
3255 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3256
3257 test_32j() {
3258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3259
3260         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3261         trap cleanup_test32_mount EXIT
3262         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3263         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3264                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3265         touch $DIR/$tdir/test_file
3266         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3267                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3268         cleanup_test32_mount
3269 }
3270 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3271
3272 test_32k() {
3273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3274
3275         rm -fr $DIR/$tdir
3276         trap cleanup_test32_mount EXIT
3277         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3278         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3279                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3280         test_mkdir -p $DIR/$tdir/d2
3281         touch $DIR/$tdir/d2/test_file || error "touch failed"
3282         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3283                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3284         cleanup_test32_mount
3285 }
3286 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3287
3288 test_32l() {
3289         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3290
3291         rm -fr $DIR/$tdir
3292         trap cleanup_test32_mount EXIT
3293         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3294         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3295                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3296         test_mkdir -p $DIR/$tdir/d2
3297         touch $DIR/$tdir/d2/test_file || error "touch failed"
3298         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3299                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3300         cleanup_test32_mount
3301 }
3302 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3303
3304 test_32m() {
3305         rm -fr $DIR/d32m
3306         test_mkdir -p $DIR/d32m/tmp
3307         TMP_DIR=$DIR/d32m/tmp
3308         ln -s $DIR $TMP_DIR/symlink11
3309         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3310         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3311                 error "symlink11 not a link"
3312         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3313                 error "symlink01 not a link"
3314 }
3315 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3316
3317 test_32n() {
3318         rm -fr $DIR/d32n
3319         test_mkdir -p $DIR/d32n/tmp
3320         TMP_DIR=$DIR/d32n/tmp
3321         ln -s $DIR $TMP_DIR/symlink11
3322         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3323         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3324         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3325 }
3326 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3327
3328 test_32o() {
3329         touch $DIR/$tfile
3330         test_mkdir -p $DIR/d32o/tmp
3331         TMP_DIR=$DIR/d32o/tmp
3332         ln -s $DIR/$tfile $TMP_DIR/symlink12
3333         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3334         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3335                 error "symlink12 not a link"
3336         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3337         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3338                 error "$DIR/d32o/tmp/symlink12 not file type"
3339         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3340                 error "$DIR/d32o/symlink02 not file type"
3341 }
3342 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3343
3344 test_32p() {
3345         log 32p_1
3346         rm -fr $DIR/d32p
3347         log 32p_2
3348         rm -f $DIR/$tfile
3349         log 32p_3
3350         touch $DIR/$tfile
3351         log 32p_4
3352         test_mkdir -p $DIR/d32p/tmp
3353         log 32p_5
3354         TMP_DIR=$DIR/d32p/tmp
3355         log 32p_6
3356         ln -s $DIR/$tfile $TMP_DIR/symlink12
3357         log 32p_7
3358         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3359         log 32p_8
3360         cat $DIR/d32p/tmp/symlink12 ||
3361                 error "Can't open $DIR/d32p/tmp/symlink12"
3362         log 32p_9
3363         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3364         log 32p_10
3365 }
3366 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3367
3368 test_32q() {
3369         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3370
3371         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3372         trap cleanup_test32_mount EXIT
3373         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3374         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3375         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3376                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3377         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3378         cleanup_test32_mount
3379 }
3380 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3381
3382 test_32r() {
3383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3384
3385         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3386         trap cleanup_test32_mount EXIT
3387         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3388         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3389         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3390                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3391         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3392         cleanup_test32_mount
3393 }
3394 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3395
3396 test_33aa() {
3397         rm -f $DIR/$tfile
3398         touch $DIR/$tfile
3399         chmod 444 $DIR/$tfile
3400         chown $RUNAS_ID $DIR/$tfile
3401         log 33_1
3402         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3403         log 33_2
3404 }
3405 run_test 33aa "write file with mode 444 (should return error)"
3406
3407 test_33a() {
3408         rm -fr $DIR/$tdir
3409         test_mkdir $DIR/$tdir
3410         chown $RUNAS_ID $DIR/$tdir
3411         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3412                 error "$RUNAS create $tdir/$tfile failed"
3413         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3414                 error "open RDWR" || true
3415 }
3416 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3417
3418 test_33b() {
3419         rm -fr $DIR/$tdir
3420         test_mkdir $DIR/$tdir
3421         chown $RUNAS_ID $DIR/$tdir
3422         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3423 }
3424 run_test 33b "test open file with malformed flags (No panic)"
3425
3426 test_33c() {
3427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3428         remote_ost_nodsh && skip "remote OST with nodsh"
3429
3430         local ostnum
3431         local ostname
3432         local write_bytes
3433         local all_zeros
3434
3435         all_zeros=:
3436         rm -fr $DIR/$tdir
3437         test_mkdir $DIR/$tdir
3438         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3439
3440         sync
3441         for ostnum in $(seq $OSTCOUNT); do
3442                 # test-framework's OST numbering is one-based, while Lustre's
3443                 # is zero-based
3444                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3445                 # Parsing llobdstat's output sucks; we could grep the /proc
3446                 # path, but that's likely to not be as portable as using the
3447                 # llobdstat utility.  So we parse lctl output instead.
3448                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3449                         obdfilter/$ostname/stats |
3450                         awk '/^write_bytes/ {print $7}' )
3451                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3452                 if (( ${write_bytes:-0} > 0 ))
3453                 then
3454                         all_zeros=false
3455                         break;
3456                 fi
3457         done
3458
3459         $all_zeros || return 0
3460
3461         # Write four bytes
3462         echo foo > $DIR/$tdir/bar
3463         # Really write them
3464         sync
3465
3466         # Total up write_bytes after writing.  We'd better find non-zeros.
3467         for ostnum in $(seq $OSTCOUNT); do
3468                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3469                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3470                         obdfilter/$ostname/stats |
3471                         awk '/^write_bytes/ {print $7}' )
3472                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3473                 if (( ${write_bytes:-0} > 0 ))
3474                 then
3475                         all_zeros=false
3476                         break;
3477                 fi
3478         done
3479
3480         if $all_zeros
3481         then
3482                 for ostnum in $(seq $OSTCOUNT); do
3483                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3484                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3485                         do_facet ost$ostnum lctl get_param -n \
3486                                 obdfilter/$ostname/stats
3487                 done
3488                 error "OST not keeping write_bytes stats (b22312)"
3489         fi
3490 }
3491 run_test 33c "test llobdstat and write_bytes"
3492
3493 test_33d() {
3494         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3496
3497         local MDTIDX=1
3498         local remote_dir=$DIR/$tdir/remote_dir
3499
3500         test_mkdir $DIR/$tdir
3501         $LFS mkdir -i $MDTIDX $remote_dir ||
3502                 error "create remote directory failed"
3503
3504         touch $remote_dir/$tfile
3505         chmod 444 $remote_dir/$tfile
3506         chown $RUNAS_ID $remote_dir/$tfile
3507
3508         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3509
3510         chown $RUNAS_ID $remote_dir
3511         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3512                                         error "create" || true
3513         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3514                                     error "open RDWR" || true
3515         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3516 }
3517 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3518
3519 test_33e() {
3520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3521
3522         mkdir $DIR/$tdir
3523
3524         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3525         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3526         mkdir $DIR/$tdir/local_dir
3527
3528         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3529         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3530         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3531
3532         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3533                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3534
3535         rmdir $DIR/$tdir/* || error "rmdir failed"
3536
3537         umask 777
3538         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3539         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3540         mkdir $DIR/$tdir/local_dir
3541
3542         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3543         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3544         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3545
3546         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3547                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3548
3549         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3550
3551         umask 000
3552         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3553         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3554         mkdir $DIR/$tdir/local_dir
3555
3556         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3557         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3558         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3559
3560         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3561                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3562 }
3563 run_test 33e "mkdir and striped directory should have same mode"
3564
3565 cleanup_33f() {
3566         trap 0
3567         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3568 }
3569
3570 test_33f() {
3571         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3572         remote_mds_nodsh && skip "remote MDS with nodsh"
3573
3574         mkdir $DIR/$tdir
3575         chmod go+rwx $DIR/$tdir
3576         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3577         trap cleanup_33f EXIT
3578
3579         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3580                 error "cannot create striped directory"
3581
3582         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3583                 error "cannot create files in striped directory"
3584
3585         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3586                 error "cannot remove files in striped directory"
3587
3588         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3589                 error "cannot remove striped directory"
3590
3591         cleanup_33f
3592 }
3593 run_test 33f "nonroot user can create, access, and remove a striped directory"
3594
3595 test_33g() {
3596         mkdir -p $DIR/$tdir/dir2
3597
3598         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3599         echo $err
3600         [[ $err =~ "exists" ]] || error "Not exists error"
3601 }
3602 run_test 33g "nonroot user create already existing root created file"
3603
3604 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3605 test_34a() {
3606         rm -f $DIR/f34
3607         $MCREATE $DIR/f34 || error "mcreate failed"
3608         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3609                 error "getstripe failed"
3610         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3611         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3612                 error "getstripe failed"
3613         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3614                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3615 }
3616 run_test 34a "truncate file that has not been opened ==========="
3617
3618 test_34b() {
3619         [ ! -f $DIR/f34 ] && test_34a
3620         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3621                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3622         $OPENFILE -f O_RDONLY $DIR/f34
3623         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3624                 error "getstripe failed"
3625         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3626                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3627 }
3628 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3629
3630 test_34c() {
3631         [ ! -f $DIR/f34 ] && test_34a
3632         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3633                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3634         $OPENFILE -f O_RDWR $DIR/f34
3635         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3636                 error "$LFS getstripe failed"
3637         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3638                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3639 }
3640 run_test 34c "O_RDWR opening file-with-size works =============="
3641
3642 test_34d() {
3643         [ ! -f $DIR/f34 ] && test_34a
3644         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3645                 error "dd failed"
3646         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3647                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3648         rm $DIR/f34
3649 }
3650 run_test 34d "write to sparse file ============================="
3651
3652 test_34e() {
3653         rm -f $DIR/f34e
3654         $MCREATE $DIR/f34e || error "mcreate failed"
3655         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3656         $CHECKSTAT -s 1000 $DIR/f34e ||
3657                 error "Size of $DIR/f34e not equal to 1000 bytes"
3658         $OPENFILE -f O_RDWR $DIR/f34e
3659         $CHECKSTAT -s 1000 $DIR/f34e ||
3660                 error "Size of $DIR/f34e not equal to 1000 bytes"
3661 }
3662 run_test 34e "create objects, some with size and some without =="
3663
3664 test_34f() { # bug 6242, 6243
3665         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3666
3667         SIZE34F=48000
3668         rm -f $DIR/f34f
3669         $MCREATE $DIR/f34f || error "mcreate failed"
3670         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3671         dd if=$DIR/f34f of=$TMP/f34f
3672         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3673         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3674         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3675         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3676         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3677 }
3678 run_test 34f "read from a file with no objects until EOF ======="
3679
3680 test_34g() {
3681         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3682
3683         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3684                 error "dd failed"
3685         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3686         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3687                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3688         cancel_lru_locks osc
3689         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3690                 error "wrong size after lock cancel"
3691
3692         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3693         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3694                 error "expanding truncate failed"
3695         cancel_lru_locks osc
3696         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3697                 error "wrong expanded size after lock cancel"
3698 }
3699 run_test 34g "truncate long file ==============================="
3700
3701 test_34h() {
3702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3703
3704         local gid=10
3705         local sz=1000
3706
3707         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3708         sync # Flush the cache so that multiop below does not block on cache
3709              # flush when getting the group lock
3710         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3711         MULTIPID=$!
3712
3713         # Since just timed wait is not good enough, let's do a sync write
3714         # that way we are sure enough time for a roundtrip + processing
3715         # passed + 2 seconds of extra margin.
3716         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3717         rm $DIR/${tfile}-1
3718         sleep 2
3719
3720         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3721                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3722                 kill -9 $MULTIPID
3723         fi
3724         wait $MULTIPID
3725         local nsz=`stat -c %s $DIR/$tfile`
3726         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3727 }
3728 run_test 34h "ftruncate file under grouplock should not block"
3729
3730 test_35a() {
3731         cp /bin/sh $DIR/f35a
3732         chmod 444 $DIR/f35a
3733         chown $RUNAS_ID $DIR/f35a
3734         $RUNAS $DIR/f35a && error || true
3735         rm $DIR/f35a
3736 }
3737 run_test 35a "exec file with mode 444 (should return and not leak)"
3738
3739 test_36a() {
3740         rm -f $DIR/f36
3741         utime $DIR/f36 || error "utime failed for MDS"
3742 }
3743 run_test 36a "MDS utime check (mknod, utime)"
3744
3745 test_36b() {
3746         echo "" > $DIR/f36
3747         utime $DIR/f36 || error "utime failed for OST"
3748 }
3749 run_test 36b "OST utime check (open, utime)"
3750
3751 test_36c() {
3752         rm -f $DIR/d36/f36
3753         test_mkdir $DIR/d36
3754         chown $RUNAS_ID $DIR/d36
3755         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3756 }
3757 run_test 36c "non-root MDS utime check (mknod, utime)"
3758
3759 test_36d() {
3760         [ ! -d $DIR/d36 ] && test_36c
3761         echo "" > $DIR/d36/f36
3762         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3763 }
3764 run_test 36d "non-root OST utime check (open, utime)"
3765
3766 test_36e() {
3767         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3768
3769         test_mkdir $DIR/$tdir
3770         touch $DIR/$tdir/$tfile
3771         $RUNAS utime $DIR/$tdir/$tfile &&
3772                 error "utime worked, expected failure" || true
3773 }
3774 run_test 36e "utime on non-owned file (should return error)"
3775
3776 subr_36fh() {
3777         local fl="$1"
3778         local LANG_SAVE=$LANG
3779         local LC_LANG_SAVE=$LC_LANG
3780         export LANG=C LC_LANG=C # for date language
3781
3782         DATESTR="Dec 20  2000"
3783         test_mkdir $DIR/$tdir
3784         lctl set_param fail_loc=$fl
3785         date; date +%s
3786         cp /etc/hosts $DIR/$tdir/$tfile
3787         sync & # write RPC generated with "current" inode timestamp, but delayed
3788         sleep 1
3789         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3790         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3791         cancel_lru_locks $OSC
3792         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3793         date; date +%s
3794         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3795                 echo "BEFORE: $LS_BEFORE" && \
3796                 echo "AFTER : $LS_AFTER" && \
3797                 echo "WANT  : $DATESTR" && \
3798                 error "$DIR/$tdir/$tfile timestamps changed" || true
3799
3800         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3801 }
3802
3803 test_36f() {
3804         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3805
3806         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3807         subr_36fh "0x80000214"
3808 }
3809 run_test 36f "utime on file racing with OST BRW write =========="
3810
3811 test_36g() {
3812         remote_ost_nodsh && skip "remote OST with nodsh"
3813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3814         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3815                 skip "Need MDS version at least 2.12.51"
3816
3817         local fmd_max_age
3818         local fmd
3819         local facet="ost1"
3820         local tgt="obdfilter"
3821
3822         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3823
3824         test_mkdir $DIR/$tdir
3825         fmd_max_age=$(do_facet $facet \
3826                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3827                 head -n 1")
3828
3829         echo "FMD max age: ${fmd_max_age}s"
3830         touch $DIR/$tdir/$tfile
3831         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3832                 gawk '{cnt=cnt+$1}  END{print cnt}')
3833         echo "FMD before: $fmd"
3834         [[ $fmd == 0 ]] &&
3835                 error "FMD wasn't create by touch"
3836         sleep $((fmd_max_age + 12))
3837         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3838                 gawk '{cnt=cnt+$1}  END{print cnt}')
3839         echo "FMD after: $fmd"
3840         [[ $fmd == 0 ]] ||
3841                 error "FMD wasn't expired by ping"
3842 }
3843 run_test 36g "FMD cache expiry ====================="
3844
3845 test_36h() {
3846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3847
3848         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3849         subr_36fh "0x80000227"
3850 }
3851 run_test 36h "utime on file racing with OST BRW write =========="
3852
3853 test_36i() {
3854         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3855
3856         test_mkdir $DIR/$tdir
3857         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3858
3859         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3860         local new_mtime=$((mtime + 200))
3861
3862         #change Modify time of striped dir
3863         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
3864                         error "change mtime failed"
3865
3866         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
3867
3868         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
3869 }
3870 run_test 36i "change mtime on striped directory"
3871
3872 # test_37 - duplicate with tests 32q 32r
3873
3874 test_38() {
3875         local file=$DIR/$tfile
3876         touch $file
3877         openfile -f O_DIRECTORY $file
3878         local RC=$?
3879         local ENOTDIR=20
3880         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
3881         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
3882 }
3883 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
3884
3885 test_39a() { # was test_39
3886         touch $DIR/$tfile
3887         touch $DIR/${tfile}2
3888 #       ls -l  $DIR/$tfile $DIR/${tfile}2
3889 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
3890 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
3891         sleep 2
3892         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
3893         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
3894                 echo "mtime"
3895                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
3896                 echo "atime"
3897                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
3898                 echo "ctime"
3899                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
3900                 error "O_TRUNC didn't change timestamps"
3901         fi
3902 }
3903 run_test 39a "mtime changed on create"
3904
3905 test_39b() {
3906         test_mkdir -c1 $DIR/$tdir
3907         cp -p /etc/passwd $DIR/$tdir/fopen
3908         cp -p /etc/passwd $DIR/$tdir/flink
3909         cp -p /etc/passwd $DIR/$tdir/funlink
3910         cp -p /etc/passwd $DIR/$tdir/frename
3911         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
3912
3913         sleep 1
3914         echo "aaaaaa" >> $DIR/$tdir/fopen
3915         echo "aaaaaa" >> $DIR/$tdir/flink
3916         echo "aaaaaa" >> $DIR/$tdir/funlink
3917         echo "aaaaaa" >> $DIR/$tdir/frename
3918
3919         local open_new=`stat -c %Y $DIR/$tdir/fopen`
3920         local link_new=`stat -c %Y $DIR/$tdir/flink`
3921         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
3922         local rename_new=`stat -c %Y $DIR/$tdir/frename`
3923
3924         cat $DIR/$tdir/fopen > /dev/null
3925         ln $DIR/$tdir/flink $DIR/$tdir/flink2
3926         rm -f $DIR/$tdir/funlink2
3927         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
3928
3929         for (( i=0; i < 2; i++ )) ; do
3930                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
3931                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
3932                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
3933                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
3934
3935                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
3936                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
3937                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
3938                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
3939
3940                 cancel_lru_locks $OSC
3941                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3942         done
3943 }
3944 run_test 39b "mtime change on open, link, unlink, rename  ======"
3945
3946 # this should be set to past
3947 TEST_39_MTIME=`date -d "1 year ago" +%s`
3948
3949 # bug 11063
3950 test_39c() {
3951         touch $DIR1/$tfile
3952         sleep 2
3953         local mtime0=`stat -c %Y $DIR1/$tfile`
3954
3955         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3956         local mtime1=`stat -c %Y $DIR1/$tfile`
3957         [ "$mtime1" = $TEST_39_MTIME ] || \
3958                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
3959
3960         local d1=`date +%s`
3961         echo hello >> $DIR1/$tfile
3962         local d2=`date +%s`
3963         local mtime2=`stat -c %Y $DIR1/$tfile`
3964         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
3965                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
3966
3967         mv $DIR1/$tfile $DIR1/$tfile-1
3968
3969         for (( i=0; i < 2; i++ )) ; do
3970                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
3971                 [ "$mtime2" = "$mtime3" ] || \
3972                         error "mtime ($mtime2) changed (to $mtime3) on rename"
3973
3974                 cancel_lru_locks $OSC
3975                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3976         done
3977 }
3978 run_test 39c "mtime change on rename ==========================="
3979
3980 # bug 21114
3981 test_39d() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983
3984         touch $DIR1/$tfile
3985         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
3986
3987         for (( i=0; i < 2; i++ )) ; do
3988                 local mtime=`stat -c %Y $DIR1/$tfile`
3989                 [ $mtime = $TEST_39_MTIME ] || \
3990                         error "mtime($mtime) is not set to $TEST_39_MTIME"
3991
3992                 cancel_lru_locks $OSC
3993                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
3994         done
3995 }
3996 run_test 39d "create, utime, stat =============================="
3997
3998 # bug 21114
3999 test_39e() {
4000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4001
4002         touch $DIR1/$tfile
4003         local mtime1=`stat -c %Y $DIR1/$tfile`
4004
4005         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4006
4007         for (( i=0; i < 2; i++ )) ; do
4008                 local mtime2=`stat -c %Y $DIR1/$tfile`
4009                 [ $mtime2 = $TEST_39_MTIME ] || \
4010                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4011
4012                 cancel_lru_locks $OSC
4013                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4014         done
4015 }
4016 run_test 39e "create, stat, utime, stat ========================"
4017
4018 # bug 21114
4019 test_39f() {
4020         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4021
4022         touch $DIR1/$tfile
4023         mtime1=`stat -c %Y $DIR1/$tfile`
4024
4025         sleep 2
4026         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4027
4028         for (( i=0; i < 2; i++ )) ; do
4029                 local mtime2=`stat -c %Y $DIR1/$tfile`
4030                 [ $mtime2 = $TEST_39_MTIME ] || \
4031                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4032
4033                 cancel_lru_locks $OSC
4034                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4035         done
4036 }
4037 run_test 39f "create, stat, sleep, utime, stat ================="
4038
4039 # bug 11063
4040 test_39g() {
4041         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4042
4043         echo hello >> $DIR1/$tfile
4044         local mtime1=`stat -c %Y $DIR1/$tfile`
4045
4046         sleep 2
4047         chmod o+r $DIR1/$tfile
4048
4049         for (( i=0; i < 2; i++ )) ; do
4050                 local mtime2=`stat -c %Y $DIR1/$tfile`
4051                 [ "$mtime1" = "$mtime2" ] || \
4052                         error "lost mtime: $mtime2, should be $mtime1"
4053
4054                 cancel_lru_locks $OSC
4055                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4056         done
4057 }
4058 run_test 39g "write, chmod, stat ==============================="
4059
4060 # bug 11063
4061 test_39h() {
4062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4063
4064         touch $DIR1/$tfile
4065         sleep 1
4066
4067         local d1=`date`
4068         echo hello >> $DIR1/$tfile
4069         local mtime1=`stat -c %Y $DIR1/$tfile`
4070
4071         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4072         local d2=`date`
4073         if [ "$d1" != "$d2" ]; then
4074                 echo "write and touch not within one second"
4075         else
4076                 for (( i=0; i < 2; i++ )) ; do
4077                         local mtime2=`stat -c %Y $DIR1/$tfile`
4078                         [ "$mtime2" = $TEST_39_MTIME ] || \
4079                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4080
4081                         cancel_lru_locks $OSC
4082                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4083                 done
4084         fi
4085 }
4086 run_test 39h "write, utime within one second, stat ============="
4087
4088 test_39i() {
4089         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4090
4091         touch $DIR1/$tfile
4092         sleep 1
4093
4094         echo hello >> $DIR1/$tfile
4095         local mtime1=`stat -c %Y $DIR1/$tfile`
4096
4097         mv $DIR1/$tfile $DIR1/$tfile-1
4098
4099         for (( i=0; i < 2; i++ )) ; do
4100                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4101
4102                 [ "$mtime1" = "$mtime2" ] || \
4103                         error "lost mtime: $mtime2, should be $mtime1"
4104
4105                 cancel_lru_locks $OSC
4106                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4107         done
4108 }
4109 run_test 39i "write, rename, stat =============================="
4110
4111 test_39j() {
4112         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4113
4114         start_full_debug_logging
4115         touch $DIR1/$tfile
4116         sleep 1
4117
4118         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4119         lctl set_param fail_loc=0x80000412
4120         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4121                 error "multiop failed"
4122         local multipid=$!
4123         local mtime1=`stat -c %Y $DIR1/$tfile`
4124
4125         mv $DIR1/$tfile $DIR1/$tfile-1
4126
4127         kill -USR1 $multipid
4128         wait $multipid || error "multiop close failed"
4129
4130         for (( i=0; i < 2; i++ )) ; do
4131                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4132                 [ "$mtime1" = "$mtime2" ] ||
4133                         error "mtime is lost on close: $mtime2, " \
4134                               "should be $mtime1"
4135
4136                 cancel_lru_locks $OSC
4137                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4138         done
4139         lctl set_param fail_loc=0
4140         stop_full_debug_logging
4141 }
4142 run_test 39j "write, rename, close, stat ======================="
4143
4144 test_39k() {
4145         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4146
4147         touch $DIR1/$tfile
4148         sleep 1
4149
4150         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4151         local multipid=$!
4152         local mtime1=`stat -c %Y $DIR1/$tfile`
4153
4154         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4155
4156         kill -USR1 $multipid
4157         wait $multipid || error "multiop close failed"
4158
4159         for (( i=0; i < 2; i++ )) ; do
4160                 local mtime2=`stat -c %Y $DIR1/$tfile`
4161
4162                 [ "$mtime2" = $TEST_39_MTIME ] || \
4163                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4164
4165                 cancel_lru_locks osc
4166                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4167         done
4168 }
4169 run_test 39k "write, utime, close, stat ========================"
4170
4171 # this should be set to future
4172 TEST_39_ATIME=`date -d "1 year" +%s`
4173
4174 test_39l() {
4175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4176         remote_mds_nodsh && skip "remote MDS with nodsh"
4177
4178         local atime_diff=$(do_facet $SINGLEMDS \
4179                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4180         rm -rf $DIR/$tdir
4181         mkdir -p $DIR/$tdir
4182
4183         # test setting directory atime to future
4184         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4185         local atime=$(stat -c %X $DIR/$tdir)
4186         [ "$atime" = $TEST_39_ATIME ] ||
4187                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4188
4189         # test setting directory atime from future to now
4190         local now=$(date +%s)
4191         touch -a -d @$now $DIR/$tdir
4192
4193         atime=$(stat -c %X $DIR/$tdir)
4194         [ "$atime" -eq "$now"  ] ||
4195                 error "atime is not updated from future: $atime, $now"
4196
4197         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4198         sleep 3
4199
4200         # test setting directory atime when now > dir atime + atime_diff
4201         local d1=$(date +%s)
4202         ls $DIR/$tdir
4203         local d2=$(date +%s)
4204         cancel_lru_locks mdc
4205         atime=$(stat -c %X $DIR/$tdir)
4206         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4207                 error "atime is not updated  : $atime, should be $d2"
4208
4209         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4210         sleep 3
4211
4212         # test not setting directory atime when now < dir atime + atime_diff
4213         ls $DIR/$tdir
4214         cancel_lru_locks mdc
4215         atime=$(stat -c %X $DIR/$tdir)
4216         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4217                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4218
4219         do_facet $SINGLEMDS \
4220                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4221 }
4222 run_test 39l "directory atime update ==========================="
4223
4224 test_39m() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         sleep 2
4229         local far_past_mtime=$(date -d "May 29 1953" +%s)
4230         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4231
4232         touch -m -d @$far_past_mtime $DIR1/$tfile
4233         touch -a -d @$far_past_atime $DIR1/$tfile
4234
4235         for (( i=0; i < 2; i++ )) ; do
4236                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4237                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4238                         error "atime or mtime set incorrectly"
4239
4240                 cancel_lru_locks $OSC
4241                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4242         done
4243 }
4244 run_test 39m "test atime and mtime before 1970"
4245
4246 test_39n() { # LU-3832
4247         remote_mds_nodsh && skip "remote MDS with nodsh"
4248
4249         local atime_diff=$(do_facet $SINGLEMDS \
4250                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4251         local atime0
4252         local atime1
4253         local atime2
4254
4255         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4256
4257         rm -rf $DIR/$tfile
4258         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4259         atime0=$(stat -c %X $DIR/$tfile)
4260
4261         sleep 5
4262         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4263         atime1=$(stat -c %X $DIR/$tfile)
4264
4265         sleep 5
4266         cancel_lru_locks mdc
4267         cancel_lru_locks osc
4268         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4269         atime2=$(stat -c %X $DIR/$tfile)
4270
4271         do_facet $SINGLEMDS \
4272                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4273
4274         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4275         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4276 }
4277 run_test 39n "check that O_NOATIME is honored"
4278
4279 test_39o() {
4280         TESTDIR=$DIR/$tdir/$tfile
4281         [ -e $TESTDIR ] && rm -rf $TESTDIR
4282         mkdir -p $TESTDIR
4283         cd $TESTDIR
4284         links1=2
4285         ls
4286         mkdir a b
4287         ls
4288         links2=$(stat -c %h .)
4289         [ $(($links1 + 2)) != $links2 ] &&
4290                 error "wrong links count $(($links1 + 2)) != $links2"
4291         rmdir b
4292         links3=$(stat -c %h .)
4293         [ $(($links1 + 1)) != $links3 ] &&
4294                 error "wrong links count $links1 != $links3"
4295         return 0
4296 }
4297 run_test 39o "directory cached attributes updated after create"
4298
4299 test_39p() {
4300         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4301
4302         local MDTIDX=1
4303         TESTDIR=$DIR/$tdir/$tdir
4304         [ -e $TESTDIR ] && rm -rf $TESTDIR
4305         test_mkdir -p $TESTDIR
4306         cd $TESTDIR
4307         links1=2
4308         ls
4309         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4310         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4311         ls
4312         links2=$(stat -c %h .)
4313         [ $(($links1 + 2)) != $links2 ] &&
4314                 error "wrong links count $(($links1 + 2)) != $links2"
4315         rmdir remote_dir2
4316         links3=$(stat -c %h .)
4317         [ $(($links1 + 1)) != $links3 ] &&
4318                 error "wrong links count $links1 != $links3"
4319         return 0
4320 }
4321 run_test 39p "remote directory cached attributes updated after create ========"
4322
4323
4324 test_39q() { # LU-8041
4325         local testdir=$DIR/$tdir
4326         mkdir -p $testdir
4327         multiop_bg_pause $testdir D_c || error "multiop failed"
4328         local multipid=$!
4329         cancel_lru_locks mdc
4330         kill -USR1 $multipid
4331         local atime=$(stat -c %X $testdir)
4332         [ "$atime" -ne 0 ] || error "atime is zero"
4333 }
4334 run_test 39q "close won't zero out atime"
4335
4336 test_40() {
4337         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4338         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4339                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4340         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4341                 error "$tfile is not 4096 bytes in size"
4342 }
4343 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4344
4345 test_41() {
4346         # bug 1553
4347         small_write $DIR/f41 18
4348 }
4349 run_test 41 "test small file write + fstat ====================="
4350
4351 count_ost_writes() {
4352         lctl get_param -n ${OSC}.*.stats |
4353                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4354                         END { printf("%0.0f", writes) }'
4355 }
4356
4357 # decent default
4358 WRITEBACK_SAVE=500
4359 DIRTY_RATIO_SAVE=40
4360 MAX_DIRTY_RATIO=50
4361 BG_DIRTY_RATIO_SAVE=10
4362 MAX_BG_DIRTY_RATIO=25
4363
4364 start_writeback() {
4365         trap 0
4366         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4367         # dirty_ratio, dirty_background_ratio
4368         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4369                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4370                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4371                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4372         else
4373                 # if file not here, we are a 2.4 kernel
4374                 kill -CONT `pidof kupdated`
4375         fi
4376 }
4377
4378 stop_writeback() {
4379         # setup the trap first, so someone cannot exit the test at the
4380         # exact wrong time and mess up a machine
4381         trap start_writeback EXIT
4382         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4383         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4384                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4385                 sysctl -w vm.dirty_writeback_centisecs=0
4386                 sysctl -w vm.dirty_writeback_centisecs=0
4387                 # save and increase /proc/sys/vm/dirty_ratio
4388                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4389                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4390                 # save and increase /proc/sys/vm/dirty_background_ratio
4391                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4392                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4393         else
4394                 # if file not here, we are a 2.4 kernel
4395                 kill -STOP `pidof kupdated`
4396         fi
4397 }
4398
4399 # ensure that all stripes have some grant before we test client-side cache
4400 setup_test42() {
4401         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4402                 dd if=/dev/zero of=$i bs=4k count=1
4403                 rm $i
4404         done
4405 }
4406
4407 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4408 # file truncation, and file removal.
4409 test_42a() {
4410         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4411
4412         setup_test42
4413         cancel_lru_locks $OSC
4414         stop_writeback
4415         sync; sleep 1; sync # just to be safe
4416         BEFOREWRITES=`count_ost_writes`
4417         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4418         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4419         AFTERWRITES=`count_ost_writes`
4420         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4421                 error "$BEFOREWRITES < $AFTERWRITES"
4422         start_writeback
4423 }
4424 run_test 42a "ensure that we don't flush on close"
4425
4426 test_42b() {
4427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4428
4429         setup_test42
4430         cancel_lru_locks $OSC
4431         stop_writeback
4432         sync
4433         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4434         BEFOREWRITES=$(count_ost_writes)
4435         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4436         AFTERWRITES=$(count_ost_writes)
4437         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4438                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4439         fi
4440         BEFOREWRITES=$(count_ost_writes)
4441         sync || error "sync: $?"
4442         AFTERWRITES=$(count_ost_writes)
4443         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4444                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4445         fi
4446         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4447         start_writeback
4448         return 0
4449 }
4450 run_test 42b "test destroy of file with cached dirty data ======"
4451
4452 # if these tests just want to test the effect of truncation,
4453 # they have to be very careful.  consider:
4454 # - the first open gets a {0,EOF}PR lock
4455 # - the first write conflicts and gets a {0, count-1}PW
4456 # - the rest of the writes are under {count,EOF}PW
4457 # - the open for truncate tries to match a {0,EOF}PR
4458 #   for the filesize and cancels the PWs.
4459 # any number of fixes (don't get {0,EOF} on open, match
4460 # composite locks, do smarter file size management) fix
4461 # this, but for now we want these tests to verify that
4462 # the cancellation with truncate intent works, so we
4463 # start the file with a full-file pw lock to match against
4464 # until the truncate.
4465 trunc_test() {
4466         test=$1
4467         file=$DIR/$test
4468         offset=$2
4469         cancel_lru_locks $OSC
4470         stop_writeback
4471         # prime the file with 0,EOF PW to match
4472         touch $file
4473         $TRUNCATE $file 0
4474         sync; sync
4475         # now the real test..
4476         dd if=/dev/zero of=$file bs=1024 count=100
4477         BEFOREWRITES=`count_ost_writes`
4478         $TRUNCATE $file $offset
4479         cancel_lru_locks $OSC
4480         AFTERWRITES=`count_ost_writes`
4481         start_writeback
4482 }
4483
4484 test_42c() {
4485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4486
4487         trunc_test 42c 1024
4488         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4489                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4490         rm $file
4491 }
4492 run_test 42c "test partial truncate of file with cached dirty data"
4493
4494 test_42d() {
4495         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4496
4497         trunc_test 42d 0
4498         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4499                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4500         rm $file
4501 }
4502 run_test 42d "test complete truncate of file with cached dirty data"
4503
4504 test_42e() { # bug22074
4505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4506
4507         local TDIR=$DIR/${tdir}e
4508         local pages=16 # hardcoded 16 pages, don't change it.
4509         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4510         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4511         local max_dirty_mb
4512         local warmup_files
4513
4514         test_mkdir $DIR/${tdir}e
4515         $LFS setstripe -c 1 $TDIR
4516         createmany -o $TDIR/f $files
4517
4518         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4519
4520         # we assume that with $OSTCOUNT files, at least one of them will
4521         # be allocated on OST0.
4522         warmup_files=$((OSTCOUNT * max_dirty_mb))
4523         createmany -o $TDIR/w $warmup_files
4524
4525         # write a large amount of data into one file and sync, to get good
4526         # avail_grant number from OST.
4527         for ((i=0; i<$warmup_files; i++)); do
4528                 idx=$($LFS getstripe -i $TDIR/w$i)
4529                 [ $idx -ne 0 ] && continue
4530                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4531                 break
4532         done
4533         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4534         sync
4535         $LCTL get_param $proc_osc0/cur_dirty_bytes
4536         $LCTL get_param $proc_osc0/cur_grant_bytes
4537
4538         # create as much dirty pages as we can while not to trigger the actual
4539         # RPCs directly. but depends on the env, VFS may trigger flush during this
4540         # period, hopefully we are good.
4541         for ((i=0; i<$warmup_files; i++)); do
4542                 idx=$($LFS getstripe -i $TDIR/w$i)
4543                 [ $idx -ne 0 ] && continue
4544                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4545         done
4546         $LCTL get_param $proc_osc0/cur_dirty_bytes
4547         $LCTL get_param $proc_osc0/cur_grant_bytes
4548
4549         # perform the real test
4550         $LCTL set_param $proc_osc0/rpc_stats 0
4551         for ((;i<$files; i++)); do
4552                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4553                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4554         done
4555         sync
4556         $LCTL get_param $proc_osc0/rpc_stats
4557
4558         local percent=0
4559         local have_ppr=false
4560         $LCTL get_param $proc_osc0/rpc_stats |
4561                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4562                         # skip lines until we are at the RPC histogram data
4563                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4564                         $have_ppr || continue
4565
4566                         # we only want the percent stat for < 16 pages
4567                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4568
4569                         percent=$((percent + WPCT))
4570                         if [[ $percent -gt 15 ]]; then
4571                                 error "less than 16-pages write RPCs" \
4572                                       "$percent% > 15%"
4573                                 break
4574                         fi
4575                 done
4576         rm -rf $TDIR
4577 }
4578 run_test 42e "verify sub-RPC writes are not done synchronously"
4579
4580 test_43A() { # was test_43
4581         test_mkdir $DIR/$tdir
4582         cp -p /bin/ls $DIR/$tdir/$tfile
4583         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4584         pid=$!
4585         # give multiop a chance to open
4586         sleep 1
4587
4588         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4589         kill -USR1 $pid
4590 }
4591 run_test 43A "execution of file opened for write should return -ETXTBSY"
4592
4593 test_43a() {
4594         test_mkdir $DIR/$tdir
4595         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4596         $DIR/$tdir/sleep 60 &
4597         SLEEP_PID=$!
4598         # Make sure exec of $tdir/sleep wins race with truncate
4599         sleep 1
4600         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4601         kill $SLEEP_PID
4602 }
4603 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4604
4605 test_43b() {
4606         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4607
4608         test_mkdir $DIR/$tdir
4609         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4610         $DIR/$tdir/sleep 60 &
4611         SLEEP_PID=$!
4612         # Make sure exec of $tdir/sleep wins race with truncate
4613         sleep 1
4614         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4615         kill $SLEEP_PID
4616 }
4617 run_test 43b "truncate of file being executed should return -ETXTBSY"
4618
4619 test_43c() {
4620         local testdir="$DIR/$tdir"
4621         test_mkdir $testdir
4622         cp $SHELL $testdir/
4623         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4624                 ( cd $testdir && md5sum -c )
4625 }
4626 run_test 43c "md5sum of copy into lustre"
4627
4628 test_44A() { # was test_44
4629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4630
4631         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4632         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4633 }
4634 run_test 44A "zero length read from a sparse stripe"
4635
4636 test_44a() {
4637         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4638                 awk '{ print $2 }')
4639         [ -z "$nstripe" ] && skip "can't get stripe info"
4640         [[ $nstripe -gt $OSTCOUNT ]] &&
4641                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4642
4643         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4644                 awk '{ print $2 }')
4645         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4646                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4647                         awk '{ print $2 }')
4648         fi
4649
4650         OFFSETS="0 $((stride/2)) $((stride-1))"
4651         for offset in $OFFSETS; do
4652                 for i in $(seq 0 $((nstripe-1))); do
4653                         local GLOBALOFFSETS=""
4654                         # size in Bytes
4655                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4656                         local myfn=$DIR/d44a-$size
4657                         echo "--------writing $myfn at $size"
4658                         ll_sparseness_write $myfn $size ||
4659                                 error "ll_sparseness_write"
4660                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4661                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4662                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4663
4664                         for j in $(seq 0 $((nstripe-1))); do
4665                                 # size in Bytes
4666                                 size=$((((j + $nstripe )*$stride + $offset)))
4667                                 ll_sparseness_write $myfn $size ||
4668                                         error "ll_sparseness_write"
4669                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4670                         done
4671                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4672                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4673                         rm -f $myfn
4674                 done
4675         done
4676 }
4677 run_test 44a "test sparse pwrite ==============================="
4678
4679 dirty_osc_total() {
4680         tot=0
4681         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4682                 tot=$(($tot + $d))
4683         done
4684         echo $tot
4685 }
4686 do_dirty_record() {
4687         before=`dirty_osc_total`
4688         echo executing "\"$*\""
4689         eval $*
4690         after=`dirty_osc_total`
4691         echo before $before, after $after
4692 }
4693 test_45() {
4694         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4695
4696         f="$DIR/f45"
4697         # Obtain grants from OST if it supports it
4698         echo blah > ${f}_grant
4699         stop_writeback
4700         sync
4701         do_dirty_record "echo blah > $f"
4702         [[ $before -eq $after ]] && error "write wasn't cached"
4703         do_dirty_record "> $f"
4704         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4705         do_dirty_record "echo blah > $f"
4706         [[ $before -eq $after ]] && error "write wasn't cached"
4707         do_dirty_record "sync"
4708         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4709         do_dirty_record "echo blah > $f"
4710         [[ $before -eq $after ]] && error "write wasn't cached"
4711         do_dirty_record "cancel_lru_locks osc"
4712         [[ $before -gt $after ]] ||
4713                 error "lock cancellation didn't lower dirty count"
4714         start_writeback
4715 }
4716 run_test 45 "osc io page accounting ============================"
4717
4718 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4719 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4720 # objects offset and an assert hit when an rpc was built with 1023's mapped
4721 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4722 test_46() {
4723         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4724
4725         f="$DIR/f46"
4726         stop_writeback
4727         sync
4728         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4729         sync
4730         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4731         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4732         sync
4733         start_writeback
4734 }
4735 run_test 46 "dirtying a previously written page ================"
4736
4737 # test_47 is removed "Device nodes check" is moved to test_28
4738
4739 test_48a() { # bug 2399
4740         [ "$mds1_FSTYPE" = "zfs" ] &&
4741         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4742                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4743
4744         test_mkdir $DIR/$tdir
4745         cd $DIR/$tdir
4746         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4747         test_mkdir $DIR/$tdir
4748         touch foo || error "'touch foo' failed after recreating cwd"
4749         test_mkdir bar
4750         touch .foo || error "'touch .foo' failed after recreating cwd"
4751         test_mkdir .bar
4752         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4753         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4754         cd . || error "'cd .' failed after recreating cwd"
4755         mkdir . && error "'mkdir .' worked after recreating cwd"
4756         rmdir . && error "'rmdir .' worked after recreating cwd"
4757         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4758         cd .. || error "'cd ..' failed after recreating cwd"
4759 }
4760 run_test 48a "Access renamed working dir (should return errors)="
4761
4762 test_48b() { # bug 2399
4763         rm -rf $DIR/$tdir
4764         test_mkdir $DIR/$tdir
4765         cd $DIR/$tdir
4766         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4767         touch foo && error "'touch foo' worked after removing cwd"
4768         mkdir foo && error "'mkdir foo' worked after removing cwd"
4769         touch .foo && error "'touch .foo' worked after removing cwd"
4770         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4771         ls . > /dev/null && error "'ls .' worked after removing cwd"
4772         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4773         mkdir . && error "'mkdir .' worked after removing cwd"
4774         rmdir . && error "'rmdir .' worked after removing cwd"
4775         ln -s . foo && error "'ln -s .' worked after removing cwd"
4776         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4777 }
4778 run_test 48b "Access removed working dir (should return errors)="
4779
4780 test_48c() { # bug 2350
4781         #lctl set_param debug=-1
4782         #set -vx
4783         rm -rf $DIR/$tdir
4784         test_mkdir -p $DIR/$tdir/dir
4785         cd $DIR/$tdir/dir
4786         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4787         $TRACE touch foo && error "touch foo worked after removing cwd"
4788         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4789         touch .foo && error "touch .foo worked after removing cwd"
4790         mkdir .foo && error "mkdir .foo worked after removing cwd"
4791         $TRACE ls . && error "'ls .' worked after removing cwd"
4792         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4793         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4794         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4795         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4796         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4797 }
4798 run_test 48c "Access removed working subdir (should return errors)"
4799
4800 test_48d() { # bug 2350
4801         #lctl set_param debug=-1
4802         #set -vx
4803         rm -rf $DIR/$tdir
4804         test_mkdir -p $DIR/$tdir/dir
4805         cd $DIR/$tdir/dir
4806         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4807         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4808         $TRACE touch foo && error "'touch foo' worked after removing parent"
4809         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4810         touch .foo && error "'touch .foo' worked after removing parent"
4811         mkdir .foo && error "mkdir .foo worked after removing parent"
4812         $TRACE ls . && error "'ls .' worked after removing parent"
4813         $TRACE ls .. && error "'ls ..' worked after removing parent"
4814         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4815         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4816         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4817         true
4818 }
4819 run_test 48d "Access removed parent subdir (should return errors)"
4820
4821 test_48e() { # bug 4134
4822         #lctl set_param debug=-1
4823         #set -vx
4824         rm -rf $DIR/$tdir
4825         test_mkdir -p $DIR/$tdir/dir
4826         cd $DIR/$tdir/dir
4827         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4828         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4829         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4830         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4831         # On a buggy kernel addition of "touch foo" after cd .. will
4832         # produce kernel oops in lookup_hash_it
4833         touch ../foo && error "'cd ..' worked after recreate parent"
4834         cd $DIR
4835         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4836 }
4837 run_test 48e "Access to recreated parent subdir (should return errors)"
4838
4839 test_49() { # LU-1030
4840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4841         remote_ost_nodsh && skip "remote OST with nodsh"
4842
4843         # get ost1 size - lustre-OST0000
4844         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4845                 awk '{ print $4 }')
4846         # write 800M at maximum
4847         [[ $ost1_size -lt 2 ]] && ost1_size=2
4848         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4849
4850         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4851         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4852         local dd_pid=$!
4853
4854         # change max_pages_per_rpc while writing the file
4855         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4856         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4857         # loop until dd process exits
4858         while ps ax -opid | grep -wq $dd_pid; do
4859                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4860                 sleep $((RANDOM % 5 + 1))
4861         done
4862         # restore original max_pages_per_rpc
4863         $LCTL set_param $osc1_mppc=$orig_mppc
4864         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
4865 }
4866 run_test 49 "Change max_pages_per_rpc won't break osc extent"
4867
4868 test_50() {
4869         # bug 1485
4870         test_mkdir $DIR/$tdir
4871         cd $DIR/$tdir
4872         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
4873 }
4874 run_test 50 "special situations: /proc symlinks  ==============="
4875
4876 test_51a() {    # was test_51
4877         # bug 1516 - create an empty entry right after ".." then split dir
4878         test_mkdir -c1 $DIR/$tdir
4879         touch $DIR/$tdir/foo
4880         $MCREATE $DIR/$tdir/bar
4881         rm $DIR/$tdir/foo
4882         createmany -m $DIR/$tdir/longfile 201
4883         FNUM=202
4884         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
4885                 $MCREATE $DIR/$tdir/longfile$FNUM
4886                 FNUM=$(($FNUM + 1))
4887                 echo -n "+"
4888         done
4889         echo
4890         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
4891 }
4892 run_test 51a "special situations: split htree with empty entry =="
4893
4894 cleanup_print_lfs_df () {
4895         trap 0
4896         $LFS df
4897         $LFS df -i
4898 }
4899
4900 test_51b() {
4901         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4902
4903         local dir=$DIR/$tdir
4904         local nrdirs=$((65536 + 100))
4905
4906         # cleanup the directory
4907         rm -fr $dir
4908
4909         test_mkdir -c1 $dir
4910
4911         $LFS df
4912         $LFS df -i
4913         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
4914         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
4915         [[ $numfree -lt $nrdirs ]] &&
4916                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
4917
4918         # need to check free space for the directories as well
4919         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
4920         numfree=$(( blkfree / $(fs_inode_ksize) ))
4921         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
4922
4923         trap cleanup_print_lfs_df EXIT
4924
4925         # create files
4926         createmany -d $dir/d $nrdirs || {
4927                 unlinkmany $dir/d $nrdirs
4928                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
4929         }
4930
4931         # really created :
4932         nrdirs=$(ls -U $dir | wc -l)
4933
4934         # unlink all but 100 subdirectories, then check it still works
4935         local left=100
4936         local delete=$((nrdirs - left))
4937
4938         $LFS df
4939         $LFS df -i
4940
4941         # for ldiskfs the nlink count should be 1, but this is OSD specific
4942         # and so this is listed for informational purposes only
4943         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
4944         unlinkmany -d $dir/d $delete ||
4945                 error "unlink of first $delete subdirs failed"
4946
4947         echo "nlink between: $(stat -c %h $dir)"
4948         local found=$(ls -U $dir | wc -l)
4949         [ $found -ne $left ] &&
4950                 error "can't find subdirs: found only $found, expected $left"
4951
4952         unlinkmany -d $dir/d $delete $left ||
4953                 error "unlink of second $left subdirs failed"
4954         # regardless of whether the backing filesystem tracks nlink accurately
4955         # or not, the nlink count shouldn't be more than "." and ".." here
4956         local after=$(stat -c %h $dir)
4957         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
4958                 echo "nlink after: $after"
4959
4960         cleanup_print_lfs_df
4961 }
4962 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
4963
4964 test_51d() {
4965         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4966         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
4967
4968         test_mkdir $DIR/$tdir
4969         createmany -o $DIR/$tdir/t- 1000
4970         $LFS getstripe $DIR/$tdir > $TMP/$tfile
4971         for N in $(seq 0 $((OSTCOUNT - 1))); do
4972                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
4973                         END { printf("%0.0f", objs) }' $TMP/$tfile)
4974                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
4975                         '($1 == '$N') { objs += 1 } \
4976                         END { printf("%0.0f", objs) }')
4977                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
4978         done
4979         unlinkmany $DIR/$tdir/t- 1000
4980
4981         NLAST=0
4982         for N in $(seq 1 $((OSTCOUNT - 1))); do
4983                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
4984                         error "OST $N has less objects vs OST $NLAST" \
4985                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4986                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
4987                         error "OST $N has less objects vs OST $NLAST" \
4988                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
4989
4990                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
4991                         error "OST $N has less #0 objects vs OST $NLAST" \
4992                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4993                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
4994                         error "OST $N has less #0 objects vs OST $NLAST" \
4995                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
4996                 NLAST=$N
4997         done
4998         rm -f $TMP/$tfile
4999 }
5000 run_test 51d "check object distribution"
5001
5002 test_51e() {
5003         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5004                 skip_env "ldiskfs only test"
5005         fi
5006
5007         test_mkdir -c1 $DIR/$tdir
5008         test_mkdir -c1 $DIR/$tdir/d0
5009
5010         touch $DIR/$tdir/d0/foo
5011         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5012                 error "file exceed 65000 nlink limit!"
5013         unlinkmany $DIR/$tdir/d0/f- 65001
5014         return 0
5015 }
5016 run_test 51e "check file nlink limit"
5017
5018 test_51f() {
5019         test_mkdir $DIR/$tdir
5020
5021         local max=100000
5022         local ulimit_old=$(ulimit -n)
5023         local spare=20 # number of spare fd's for scripts/libraries, etc.
5024         local mdt=$($LFS getstripe -m $DIR/$tdir)
5025         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5026
5027         echo "MDT$mdt numfree=$numfree, max=$max"
5028         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5029         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5030                 while ! ulimit -n $((numfree + spare)); do
5031                         numfree=$((numfree * 3 / 4))
5032                 done
5033                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5034         else
5035                 echo "left ulimit at $ulimit_old"
5036         fi
5037
5038         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5039                 unlinkmany $DIR/$tdir/f $numfree
5040                 error "create+open $numfree files in $DIR/$tdir failed"
5041         }
5042         ulimit -n $ulimit_old
5043
5044         # if createmany exits at 120s there will be fewer than $numfree files
5045         unlinkmany $DIR/$tdir/f $numfree || true
5046 }
5047 run_test 51f "check many open files limit"
5048
5049 test_52a() {
5050         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5051         test_mkdir $DIR/$tdir
5052         touch $DIR/$tdir/foo
5053         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5054         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5055         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5056         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5057         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5058                                         error "link worked"
5059         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5060         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5061         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5062                                                      error "lsattr"
5063         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5064         cp -r $DIR/$tdir $TMP/
5065         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5066 }
5067 run_test 52a "append-only flag test (should return errors)"
5068
5069 test_52b() {
5070         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5071         test_mkdir $DIR/$tdir
5072         touch $DIR/$tdir/foo
5073         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5074         cat test > $DIR/$tdir/foo && error "cat test worked"
5075         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5076         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5077         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5078                                         error "link worked"
5079         echo foo >> $DIR/$tdir/foo && error "echo worked"
5080         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5081         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5082         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5083         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5084                                                         error "lsattr"
5085         chattr -i $DIR/$tdir/foo || error "chattr failed"
5086
5087         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5088 }
5089 run_test 52b "immutable flag test (should return errors) ======="
5090
5091 test_53() {
5092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5093         remote_mds_nodsh && skip "remote MDS with nodsh"
5094         remote_ost_nodsh && skip "remote OST with nodsh"
5095
5096         local param
5097         local param_seq
5098         local ostname
5099         local mds_last
5100         local mds_last_seq
5101         local ost_last
5102         local ost_last_seq
5103         local ost_last_id
5104         local ostnum
5105         local node
5106         local found=false
5107         local support_last_seq=true
5108
5109         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5110                 support_last_seq=false
5111
5112         # only test MDT0000
5113         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5114         local value
5115         for value in $(do_facet $SINGLEMDS \
5116                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5117                 param=$(echo ${value[0]} | cut -d "=" -f1)
5118                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5119
5120                 if $support_last_seq; then
5121                         param_seq=$(echo $param |
5122                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5123                         mds_last_seq=$(do_facet $SINGLEMDS \
5124                                        $LCTL get_param -n $param_seq)
5125                 fi
5126                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5127
5128                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5129                 node=$(facet_active_host ost$((ostnum+1)))
5130                 param="obdfilter.$ostname.last_id"
5131                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5132                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5133                         ost_last_id=$ost_last
5134
5135                         if $support_last_seq; then
5136                                 ost_last_id=$(echo $ost_last |
5137                                               awk -F':' '{print $2}' |
5138                                               sed -e "s/^0x//g")
5139                                 ost_last_seq=$(echo $ost_last |
5140                                                awk -F':' '{print $1}')
5141                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5142                         fi
5143
5144                         if [[ $ost_last_id != $mds_last ]]; then
5145                                 error "$ost_last_id != $mds_last"
5146                         else
5147                                 found=true
5148                                 break
5149                         fi
5150                 done
5151         done
5152         $found || error "can not match last_seq/last_id for $mdtosc"
5153         return 0
5154 }
5155 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5156
5157 test_54a() {
5158         perl -MSocket -e ';' || skip "no Socket perl module installed"
5159
5160         $SOCKETSERVER $DIR/socket ||
5161                 error "$SOCKETSERVER $DIR/socket failed: $?"
5162         $SOCKETCLIENT $DIR/socket ||
5163                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5164         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5165 }
5166 run_test 54a "unix domain socket test =========================="
5167
5168 test_54b() {
5169         f="$DIR/f54b"
5170         mknod $f c 1 3
5171         chmod 0666 $f
5172         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5173 }
5174 run_test 54b "char device works in lustre ======================"
5175
5176 find_loop_dev() {
5177         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5178         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5179         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5180
5181         for i in $(seq 3 7); do
5182                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5183                 LOOPDEV=$LOOPBASE$i
5184                 LOOPNUM=$i
5185                 break
5186         done
5187 }
5188
5189 cleanup_54c() {
5190         local rc=0
5191         loopdev="$DIR/loop54c"
5192
5193         trap 0
5194         $UMOUNT $DIR/$tdir || rc=$?
5195         losetup -d $loopdev || true
5196         losetup -d $LOOPDEV || true
5197         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5198         return $rc
5199 }
5200
5201 test_54c() {
5202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5203
5204         loopdev="$DIR/loop54c"
5205
5206         find_loop_dev
5207         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5208         trap cleanup_54c EXIT
5209         mknod $loopdev b 7 $LOOPNUM
5210         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5211         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5212         losetup $loopdev $DIR/$tfile ||
5213                 error "can't set up $loopdev for $DIR/$tfile"
5214         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5215         test_mkdir $DIR/$tdir
5216         mount -t ext2 $loopdev $DIR/$tdir ||
5217                 error "error mounting $loopdev on $DIR/$tdir"
5218         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5219                 error "dd write"
5220         df $DIR/$tdir
5221         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5222                 error "dd read"
5223         cleanup_54c
5224 }
5225 run_test 54c "block device works in lustre ====================="
5226
5227 test_54d() {
5228         f="$DIR/f54d"
5229         string="aaaaaa"
5230         mknod $f p
5231         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5232 }
5233 run_test 54d "fifo device works in lustre ======================"
5234
5235 test_54e() {
5236         f="$DIR/f54e"
5237         string="aaaaaa"
5238         cp -aL /dev/console $f
5239         echo $string > $f || error "echo $string to $f failed"
5240 }
5241 run_test 54e "console/tty device works in lustre ======================"
5242
5243 test_56a() {
5244         local numfiles=3
5245         local dir=$DIR/$tdir
5246
5247         rm -rf $dir
5248         test_mkdir -p $dir/dir
5249         for i in $(seq $numfiles); do
5250                 touch $dir/file$i
5251                 touch $dir/dir/file$i
5252         done
5253
5254         local numcomp=$($LFS getstripe --component-count $dir)
5255
5256         [[ $numcomp == 0 ]] && numcomp=1
5257
5258         # test lfs getstripe with --recursive
5259         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5260
5261         [[ $filenum -eq $((numfiles * 2)) ]] ||
5262                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5263         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5264         [[ $filenum -eq $numfiles ]] ||
5265                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5266         echo "$LFS getstripe showed obdidx or l_ost_idx"
5267
5268         # test lfs getstripe with file instead of dir
5269         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5270         [[ $filenum -eq 1 ]] ||
5271                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5272         echo "$LFS getstripe file1 passed"
5273
5274         #test lfs getstripe with --verbose
5275         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5276         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5277                 error "$LFS getstripe --verbose $dir: "\
5278                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5279         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5280                 error "$LFS getstripe $dir: showed lmm_magic"
5281
5282         #test lfs getstripe with -v prints lmm_fid
5283         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5284         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5285                 error "$LFS getstripe -v $dir: "\
5286                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5287         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5288                 error "$LFS getstripe $dir: showed lmm_fid by default"
5289         echo "$LFS getstripe --verbose passed"
5290
5291         #check for FID information
5292         local fid1=$($LFS getstripe --fid $dir/file1)
5293         local fid2=$($LFS getstripe --verbose $dir/file1 |
5294                      awk '/lmm_fid: / { print $2; exit; }')
5295         local fid3=$($LFS path2fid $dir/file1)
5296
5297         [ "$fid1" != "$fid2" ] &&
5298                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5299         [ "$fid1" != "$fid3" ] &&
5300                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5301         echo "$LFS getstripe --fid passed"
5302
5303         #test lfs getstripe with --obd
5304         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5305                 error "$LFS getstripe --obd wrong_uuid: should return error"
5306
5307         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5308
5309         local ostidx=1
5310         local obduuid=$(ostuuid_from_index $ostidx)
5311         local found=$($LFS getstripe -r --obd $obduuid $dir |
5312                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5313
5314         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5315         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5316                 ((filenum--))
5317         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5318                 ((filenum--))
5319
5320         [[ $found -eq $filenum ]] ||
5321                 error "$LFS getstripe --obd: found $found expect $filenum"
5322         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5323                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5324                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5325                 error "$LFS getstripe --obd: should not show file on other obd"
5326         echo "$LFS getstripe --obd passed"
5327 }
5328 run_test 56a "check $LFS getstripe"
5329
5330 test_56b() {
5331         local dir=$DIR/$tdir
5332         local numdirs=3
5333
5334         test_mkdir $dir
5335         for i in $(seq $numdirs); do
5336                 test_mkdir $dir/dir$i
5337         done
5338
5339         # test lfs getdirstripe default mode is non-recursion, which is
5340         # different from lfs getstripe
5341         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5342
5343         [[ $dircnt -eq 1 ]] ||
5344                 error "$LFS getdirstripe: found $dircnt, not 1"
5345         dircnt=$($LFS getdirstripe --recursive $dir |
5346                 grep -c lmv_stripe_count)
5347         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5348                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5349 }
5350 run_test 56b "check $LFS getdirstripe"
5351
5352 test_56c() {
5353         remote_ost_nodsh && skip "remote OST with nodsh"
5354
5355         local ost_idx=0
5356         local ost_name=$(ostname_from_index $ost_idx)
5357         local old_status=$(ost_dev_status $ost_idx)
5358
5359         [[ -z "$old_status" ]] ||
5360                 skip_env "OST $ost_name is in $old_status status"
5361
5362         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5363         sleep_maxage
5364
5365         local new_status=$(ost_dev_status $ost_idx)
5366
5367         [[ "$new_status" = "D" ]] ||
5368                 error "OST $ost_name is in status of '$new_status', not 'D'"
5369
5370         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5371         sleep_maxage
5372
5373         new_status=$(ost_dev_status $ost_idx)
5374         [[ -z "$new_status" ]] ||
5375                 error "OST $ost_name is in status of '$new_status', not ''"
5376 }
5377 run_test 56c "check 'lfs df' showing device status"
5378
5379 NUMFILES=3
5380 NUMDIRS=3
5381 setup_56() {
5382         local local_tdir="$1"
5383         local local_numfiles="$2"
5384         local local_numdirs="$3"
5385         local dir_params="$4"
5386         local dir_stripe_params="$5"
5387
5388         if [ ! -d "$local_tdir" ] ; then
5389                 test_mkdir -p $dir_stripe_params $local_tdir
5390                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5391                 for i in $(seq $local_numfiles) ; do
5392                         touch $local_tdir/file$i
5393                 done
5394                 for i in $(seq $local_numdirs) ; do
5395                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5396                         for j in $(seq $local_numfiles) ; do
5397                                 touch $local_tdir/dir$i/file$j
5398                         done
5399                 done
5400         fi
5401 }
5402
5403 setup_56_special() {
5404         local local_tdir=$1
5405         local local_numfiles=$2
5406         local local_numdirs=$3
5407
5408         setup_56 $local_tdir $local_numfiles $local_numdirs
5409
5410         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5411                 for i in $(seq $local_numfiles) ; do
5412                         mknod $local_tdir/loop${i}b b 7 $i
5413                         mknod $local_tdir/null${i}c c 1 3
5414                         ln -s $local_tdir/file1 $local_tdir/link${i}
5415                 done
5416                 for i in $(seq $local_numdirs) ; do
5417                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5418                         mknod $local_tdir/dir$i/null${i}c c 1 3
5419                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5420                 done
5421         fi
5422 }
5423
5424 test_56g() {
5425         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5426         local expected=$(($NUMDIRS + 2))
5427
5428         setup_56 $dir $NUMFILES $NUMDIRS
5429
5430         # test lfs find with -name
5431         for i in $(seq $NUMFILES) ; do
5432                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5433
5434                 [ $nums -eq $expected ] ||
5435                         error "lfs find -name '*$i' $dir wrong: "\
5436                               "found $nums, expected $expected"
5437         done
5438 }
5439 run_test 56g "check lfs find -name"
5440
5441 test_56h() {
5442         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5443         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5444
5445         setup_56 $dir $NUMFILES $NUMDIRS
5446
5447         # test lfs find with ! -name
5448         for i in $(seq $NUMFILES) ; do
5449                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5450
5451                 [ $nums -eq $expected ] ||
5452                         error "lfs find ! -name '*$i' $dir wrong: "\
5453                               "found $nums, expected $expected"
5454         done
5455 }
5456 run_test 56h "check lfs find ! -name"
5457
5458 test_56i() {
5459         local dir=$DIR/$tdir
5460
5461         test_mkdir $dir
5462
5463         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5464         local out=$($cmd)
5465
5466         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5467 }
5468 run_test 56i "check 'lfs find -ost UUID' skips directories"
5469
5470 test_56j() {
5471         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5472
5473         setup_56_special $dir $NUMFILES $NUMDIRS
5474
5475         local expected=$((NUMDIRS + 1))
5476         local cmd="$LFS find -type d $dir"
5477         local nums=$($cmd | wc -l)
5478
5479         [ $nums -eq $expected ] ||
5480                 error "'$cmd' wrong: found $nums, expected $expected"
5481 }
5482 run_test 56j "check lfs find -type d"
5483
5484 test_56k() {
5485         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5486
5487         setup_56_special $dir $NUMFILES $NUMDIRS
5488
5489         local expected=$(((NUMDIRS + 1) * NUMFILES))
5490         local cmd="$LFS find -type f $dir"
5491         local nums=$($cmd | wc -l)
5492
5493         [ $nums -eq $expected ] ||
5494                 error "'$cmd' wrong: found $nums, expected $expected"
5495 }
5496 run_test 56k "check lfs find -type f"
5497
5498 test_56l() {
5499         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5500
5501         setup_56_special $dir $NUMFILES $NUMDIRS
5502
5503         local expected=$((NUMDIRS + NUMFILES))
5504         local cmd="$LFS find -type b $dir"
5505         local nums=$($cmd | wc -l)
5506
5507         [ $nums -eq $expected ] ||
5508                 error "'$cmd' wrong: found $nums, expected $expected"
5509 }
5510 run_test 56l "check lfs find -type b"
5511
5512 test_56m() {
5513         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5514
5515         setup_56_special $dir $NUMFILES $NUMDIRS
5516
5517         local expected=$((NUMDIRS + NUMFILES))
5518         local cmd="$LFS find -type c $dir"
5519         local nums=$($cmd | wc -l)
5520         [ $nums -eq $expected ] ||
5521                 error "'$cmd' wrong: found $nums, expected $expected"
5522 }
5523 run_test 56m "check lfs find -type c"
5524
5525 test_56n() {
5526         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5527         setup_56_special $dir $NUMFILES $NUMDIRS
5528
5529         local expected=$((NUMDIRS + NUMFILES))
5530         local cmd="$LFS find -type l $dir"
5531         local nums=$($cmd | wc -l)
5532
5533         [ $nums -eq $expected ] ||
5534                 error "'$cmd' wrong: found $nums, expected $expected"
5535 }
5536 run_test 56n "check lfs find -type l"
5537
5538 test_56o() {
5539         local dir=$DIR/$tdir
5540
5541         setup_56 $dir $NUMFILES $NUMDIRS
5542         utime $dir/file1 > /dev/null || error "utime (1)"
5543         utime $dir/file2 > /dev/null || error "utime (2)"
5544         utime $dir/dir1 > /dev/null || error "utime (3)"
5545         utime $dir/dir2 > /dev/null || error "utime (4)"
5546         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5547         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5548
5549         local expected=4
5550         local nums=$($LFS find -mtime +0 $dir | wc -l)
5551
5552         [ $nums -eq $expected ] ||
5553                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5554
5555         expected=12
5556         cmd="$LFS find -mtime 0 $dir"
5557         nums=$($cmd | wc -l)
5558         [ $nums -eq $expected ] ||
5559                 error "'$cmd' wrong: found $nums, expected $expected"
5560 }
5561 run_test 56o "check lfs find -mtime for old files"
5562
5563 test_56ob() {
5564         local dir=$DIR/$tdir
5565         local expected=1
5566         local count=0
5567
5568         # just to make sure there is something that won't be found
5569         test_mkdir $dir
5570         touch $dir/$tfile.now
5571
5572         for age in year week day hour min; do
5573                 count=$((count + 1))
5574
5575                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5576                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5577                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5578
5579                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5580                 local nums=$($cmd | wc -l)
5581                 [ $nums -eq $expected ] ||
5582                         error "'$cmd' wrong: found $nums, expected $expected"
5583
5584                 cmd="$LFS find $dir -atime $count${age:0:1}"
5585                 nums=$($cmd | wc -l)
5586                 [ $nums -eq $expected ] ||
5587                         error "'$cmd' wrong: found $nums, expected $expected"
5588         done
5589
5590         sleep 2
5591         cmd="$LFS find $dir -ctime +1s -type f"
5592         nums=$($cmd | wc -l)
5593         (( $nums == $count * 2 + 1)) ||
5594                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5595 }
5596 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5597
5598 test_56p() {
5599         [ $RUNAS_ID -eq $UID ] &&
5600                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5601
5602         local dir=$DIR/$tdir
5603
5604         setup_56 $dir $NUMFILES $NUMDIRS
5605         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5606
5607         local expected=$NUMFILES
5608         local cmd="$LFS find -uid $RUNAS_ID $dir"
5609         local nums=$($cmd | wc -l)
5610
5611         [ $nums -eq $expected ] ||
5612                 error "'$cmd' wrong: found $nums, expected $expected"
5613
5614         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5615         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5616         nums=$($cmd | wc -l)
5617         [ $nums -eq $expected ] ||
5618                 error "'$cmd' wrong: found $nums, expected $expected"
5619 }
5620 run_test 56p "check lfs find -uid and ! -uid"
5621
5622 test_56q() {
5623         [ $RUNAS_ID -eq $UID ] &&
5624                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5625
5626         local dir=$DIR/$tdir
5627
5628         setup_56 $dir $NUMFILES $NUMDIRS
5629         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5630
5631         local expected=$NUMFILES
5632         local cmd="$LFS find -gid $RUNAS_GID $dir"
5633         local nums=$($cmd | wc -l)
5634
5635         [ $nums -eq $expected ] ||
5636                 error "'$cmd' wrong: found $nums, expected $expected"
5637
5638         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5639         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5640         nums=$($cmd | wc -l)
5641         [ $nums -eq $expected ] ||
5642                 error "'$cmd' wrong: found $nums, expected $expected"
5643 }
5644 run_test 56q "check lfs find -gid and ! -gid"
5645
5646 test_56r() {
5647         local dir=$DIR/$tdir
5648
5649         setup_56 $dir $NUMFILES $NUMDIRS
5650
5651         local expected=12
5652         local cmd="$LFS find -size 0 -type f $dir"
5653         local nums=$($cmd | wc -l)
5654
5655         [ $nums -eq $expected ] ||
5656                 error "'$cmd' wrong: found $nums, expected $expected"
5657         expected=0
5658         cmd="$LFS find ! -size 0 -type f $dir"
5659         nums=$($cmd | wc -l)
5660         [ $nums -eq $expected ] ||
5661                 error "'$cmd' wrong: found $nums, expected $expected"
5662         echo "test" > $dir/$tfile
5663         echo "test2" > $dir/$tfile.2 && sync
5664         expected=1
5665         cmd="$LFS find -size 5 -type f $dir"
5666         nums=$($cmd | wc -l)
5667         [ $nums -eq $expected ] ||
5668                 error "'$cmd' wrong: found $nums, expected $expected"
5669         expected=1
5670         cmd="$LFS find -size +5 -type f $dir"
5671         nums=$($cmd | wc -l)
5672         [ $nums -eq $expected ] ||
5673                 error "'$cmd' wrong: found $nums, expected $expected"
5674         expected=2
5675         cmd="$LFS find -size +0 -type f $dir"
5676         nums=$($cmd | wc -l)
5677         [ $nums -eq $expected ] ||
5678                 error "'$cmd' wrong: found $nums, expected $expected"
5679         expected=2
5680         cmd="$LFS find ! -size -5 -type f $dir"
5681         nums=$($cmd | wc -l)
5682         [ $nums -eq $expected ] ||
5683                 error "'$cmd' wrong: found $nums, expected $expected"
5684         expected=12
5685         cmd="$LFS find -size -5 -type f $dir"
5686         nums=$($cmd | wc -l)
5687         [ $nums -eq $expected ] ||
5688                 error "'$cmd' wrong: found $nums, expected $expected"
5689 }
5690 run_test 56r "check lfs find -size works"
5691
5692 test_56s() { # LU-611 #LU-9369
5693         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5694
5695         local dir=$DIR/$tdir
5696         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5697
5698         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5699         for i in $(seq $NUMDIRS); do
5700                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5701         done
5702
5703         local expected=$NUMDIRS
5704         local cmd="$LFS find -c $OSTCOUNT $dir"
5705         local nums=$($cmd | wc -l)
5706
5707         [ $nums -eq $expected ] || {
5708                 $LFS getstripe -R $dir
5709                 error "'$cmd' wrong: found $nums, expected $expected"
5710         }
5711
5712         expected=$((NUMDIRS + onestripe))
5713         cmd="$LFS find -stripe-count +0 -type f $dir"
5714         nums=$($cmd | wc -l)
5715         [ $nums -eq $expected ] || {
5716                 $LFS getstripe -R $dir
5717                 error "'$cmd' wrong: found $nums, expected $expected"
5718         }
5719
5720         expected=$onestripe
5721         cmd="$LFS find -stripe-count 1 -type f $dir"
5722         nums=$($cmd | wc -l)
5723         [ $nums -eq $expected ] || {
5724                 $LFS getstripe -R $dir
5725                 error "'$cmd' wrong: found $nums, expected $expected"
5726         }
5727
5728         cmd="$LFS find -stripe-count -2 -type f $dir"
5729         nums=$($cmd | wc -l)
5730         [ $nums -eq $expected ] || {
5731                 $LFS getstripe -R $dir
5732                 error "'$cmd' wrong: found $nums, expected $expected"
5733         }
5734
5735         expected=0
5736         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5737         nums=$($cmd | wc -l)
5738         [ $nums -eq $expected ] || {
5739                 $LFS getstripe -R $dir
5740                 error "'$cmd' wrong: found $nums, expected $expected"
5741         }
5742 }
5743 run_test 56s "check lfs find -stripe-count works"
5744
5745 test_56t() { # LU-611 #LU-9369
5746         local dir=$DIR/$tdir
5747
5748         setup_56 $dir 0 $NUMDIRS
5749         for i in $(seq $NUMDIRS); do
5750                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5751         done
5752
5753         local expected=$NUMDIRS
5754         local cmd="$LFS find -S 8M $dir"
5755         local nums=$($cmd | wc -l)
5756
5757         [ $nums -eq $expected ] || {
5758                 $LFS getstripe -R $dir
5759                 error "'$cmd' wrong: found $nums, expected $expected"
5760         }
5761         rm -rf $dir
5762
5763         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5764
5765         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5766
5767         expected=$(((NUMDIRS + 1) * NUMFILES))
5768         cmd="$LFS find -stripe-size 512k -type f $dir"
5769         nums=$($cmd | wc -l)
5770         [ $nums -eq $expected ] ||
5771                 error "'$cmd' wrong: found $nums, expected $expected"
5772
5773         cmd="$LFS find -stripe-size +320k -type f $dir"
5774         nums=$($cmd | wc -l)
5775         [ $nums -eq $expected ] ||
5776                 error "'$cmd' wrong: found $nums, expected $expected"
5777
5778         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5779         cmd="$LFS find -stripe-size +200k -type f $dir"
5780         nums=$($cmd | wc -l)
5781         [ $nums -eq $expected ] ||
5782                 error "'$cmd' wrong: found $nums, expected $expected"
5783
5784         cmd="$LFS find -stripe-size -640k -type f $dir"
5785         nums=$($cmd | wc -l)
5786         [ $nums -eq $expected ] ||
5787                 error "'$cmd' wrong: found $nums, expected $expected"
5788
5789         expected=4
5790         cmd="$LFS find -stripe-size 256k -type f $dir"
5791         nums=$($cmd | wc -l)
5792         [ $nums -eq $expected ] ||
5793                 error "'$cmd' wrong: found $nums, expected $expected"
5794
5795         cmd="$LFS find -stripe-size -320k -type f $dir"
5796         nums=$($cmd | wc -l)
5797         [ $nums -eq $expected ] ||
5798                 error "'$cmd' wrong: found $nums, expected $expected"
5799
5800         expected=0
5801         cmd="$LFS find -stripe-size 1024k -type f $dir"
5802         nums=$($cmd | wc -l)
5803         [ $nums -eq $expected ] ||
5804                 error "'$cmd' wrong: found $nums, expected $expected"
5805 }
5806 run_test 56t "check lfs find -stripe-size works"
5807
5808 test_56u() { # LU-611
5809         local dir=$DIR/$tdir
5810
5811         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5812
5813         if [[ $OSTCOUNT -gt 1 ]]; then
5814                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5815                 onestripe=4
5816         else
5817                 onestripe=0
5818         fi
5819
5820         local expected=$(((NUMDIRS + 1) * NUMFILES))
5821         local cmd="$LFS find -stripe-index 0 -type f $dir"
5822         local nums=$($cmd | wc -l)
5823
5824         [ $nums -eq $expected ] ||
5825                 error "'$cmd' wrong: found $nums, expected $expected"
5826
5827         expected=$onestripe
5828         cmd="$LFS find -stripe-index 1 -type f $dir"
5829         nums=$($cmd | wc -l)
5830         [ $nums -eq $expected ] ||
5831                 error "'$cmd' wrong: found $nums, expected $expected"
5832
5833         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5834         nums=$($cmd | wc -l)
5835         [ $nums -eq $expected ] ||
5836                 error "'$cmd' wrong: found $nums, expected $expected"
5837
5838         expected=0
5839         # This should produce an error and not return any files
5840         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5841         nums=$($cmd 2>/dev/null | wc -l)
5842         [ $nums -eq $expected ] ||
5843                 error "'$cmd' wrong: found $nums, expected $expected"
5844
5845         if [[ $OSTCOUNT -gt 1 ]]; then
5846                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5847                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5848                 nums=$($cmd | wc -l)
5849                 [ $nums -eq $expected ] ||
5850                         error "'$cmd' wrong: found $nums, expected $expected"
5851         fi
5852 }
5853 run_test 56u "check lfs find -stripe-index works"
5854
5855 test_56v() {
5856         local mdt_idx=0
5857         local dir=$DIR/$tdir
5858
5859         setup_56 $dir $NUMFILES $NUMDIRS
5860
5861         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5862         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5863
5864         for file in $($LFS find -m $UUID $dir); do
5865                 file_midx=$($LFS getstripe -m $file)
5866                 [ $file_midx -eq $mdt_idx ] ||
5867                         error "lfs find -m $UUID != getstripe -m $file_midx"
5868         done
5869 }
5870 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
5871
5872 test_56w() {
5873         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5874         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5875
5876         local dir=$DIR/$tdir
5877
5878         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
5879
5880         local stripe_size=$($LFS getstripe -S -d $dir) ||
5881                 error "$LFS getstripe -S -d $dir failed"
5882         stripe_size=${stripe_size%% *}
5883
5884         local file_size=$((stripe_size * OSTCOUNT))
5885         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
5886         local required_space=$((file_num * file_size))
5887         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
5888                            head -n1)
5889         [[ $free_space -le $((required_space / 1024)) ]] &&
5890                 skip_env "need $required_space, have $free_space kbytes"
5891
5892         local dd_bs=65536
5893         local dd_count=$((file_size / dd_bs))
5894
5895         # write data into the files
5896         local i
5897         local j
5898         local file
5899
5900         for i in $(seq $NUMFILES); do
5901                 file=$dir/file$i
5902                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5903                         error "write data into $file failed"
5904         done
5905         for i in $(seq $NUMDIRS); do
5906                 for j in $(seq $NUMFILES); do
5907                         file=$dir/dir$i/file$j
5908                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
5909                                 error "write data into $file failed"
5910                 done
5911         done
5912
5913         # $LFS_MIGRATE will fail if hard link migration is unsupported
5914         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
5915                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
5916                         error "creating links to $dir/dir1/file1 failed"
5917         fi
5918
5919         local expected=-1
5920
5921         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
5922
5923         # lfs_migrate file
5924         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
5925
5926         echo "$cmd"
5927         eval $cmd || error "$cmd failed"
5928
5929         check_stripe_count $dir/file1 $expected
5930
5931         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
5932         then
5933                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
5934                 # OST 1 if it is on OST 0. This file is small enough to
5935                 # be on only one stripe.
5936                 file=$dir/migr_1_ost
5937                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
5938                         error "write data into $file failed"
5939                 local obdidx=$($LFS getstripe -i $file)
5940                 local oldmd5=$(md5sum $file)
5941                 local newobdidx=0
5942
5943                 [[ $obdidx -eq 0 ]] && newobdidx=1
5944                 cmd="$LFS migrate -i $newobdidx $file"
5945                 echo $cmd
5946                 eval $cmd || error "$cmd failed"
5947
5948                 local realobdix=$($LFS getstripe -i $file)
5949                 local newmd5=$(md5sum $file)
5950
5951                 [[ $newobdidx -ne $realobdix ]] &&
5952                         error "new OST is different (was=$obdidx, "\
5953                               "wanted=$newobdidx, got=$realobdix)"
5954                 [[ "$oldmd5" != "$newmd5" ]] &&
5955                         error "md5sum differ: $oldmd5, $newmd5"
5956         fi
5957
5958         # lfs_migrate dir
5959         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
5960         echo "$cmd"
5961         eval $cmd || error "$cmd failed"
5962
5963         for j in $(seq $NUMFILES); do
5964                 check_stripe_count $dir/dir1/file$j $expected
5965         done
5966
5967         # lfs_migrate works with lfs find
5968         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
5969              $LFS_MIGRATE -y -c $expected"
5970         echo "$cmd"
5971         eval $cmd || error "$cmd failed"
5972
5973         for i in $(seq 2 $NUMFILES); do
5974                 check_stripe_count $dir/file$i $expected
5975         done
5976         for i in $(seq 2 $NUMDIRS); do
5977                 for j in $(seq $NUMFILES); do
5978                 check_stripe_count $dir/dir$i/file$j $expected
5979                 done
5980         done
5981 }
5982 run_test 56w "check lfs_migrate -c stripe_count works"
5983
5984 test_56wb() {
5985         local file1=$DIR/$tdir/file1
5986         local create_pool=false
5987         local initial_pool=$($LFS getstripe -p $DIR)
5988         local pool_list=()
5989         local pool=""
5990
5991         echo -n "Creating test dir..."
5992         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
5993         echo "done."
5994
5995         echo -n "Creating test file..."
5996         touch $file1 || error "cannot create file"
5997         echo "done."
5998
5999         echo -n "Detecting existing pools..."
6000         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6001
6002         if [ ${#pool_list[@]} -gt 0 ]; then
6003                 echo "${pool_list[@]}"
6004                 for thispool in "${pool_list[@]}"; do
6005                         if [[ -z "$initial_pool" ||
6006                               "$initial_pool" != "$thispool" ]]; then
6007                                 pool="$thispool"
6008                                 echo "Using existing pool '$pool'"
6009                                 break
6010                         fi
6011                 done
6012         else
6013                 echo "none detected."
6014         fi
6015         if [ -z "$pool" ]; then
6016                 pool=${POOL:-testpool}
6017                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6018                 echo -n "Creating pool '$pool'..."
6019                 create_pool=true
6020                 pool_add $pool &> /dev/null ||
6021                         error "pool_add failed"
6022                 echo "done."
6023
6024                 echo -n "Adding target to pool..."
6025                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6026                         error "pool_add_targets failed"
6027                 echo "done."
6028         fi
6029
6030         echo -n "Setting pool using -p option..."
6031         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6032                 error "migrate failed rc = $?"
6033         echo "done."
6034
6035         echo -n "Verifying test file is in pool after migrating..."
6036         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6037                 error "file was not migrated to pool $pool"
6038         echo "done."
6039
6040         echo -n "Removing test file from pool '$pool'..."
6041         $LFS migrate $file1 &> /dev/null ||
6042                 error "cannot remove from pool"
6043         [ "$($LFS getstripe -p $file1)" ] &&
6044                 error "pool still set"
6045         echo "done."
6046
6047         echo -n "Setting pool using --pool option..."
6048         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6049                 error "migrate failed rc = $?"
6050         echo "done."
6051
6052         # Clean up
6053         rm -f $file1
6054         if $create_pool; then
6055                 destroy_test_pools 2> /dev/null ||
6056                         error "destroy test pools failed"
6057         fi
6058 }
6059 run_test 56wb "check lfs_migrate pool support"
6060
6061 test_56wc() {
6062         local file1="$DIR/$tdir/file1"
6063
6064         echo -n "Creating test dir..."
6065         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6066         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6067         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6068                 error "cannot set stripe"
6069         echo "done"
6070
6071         echo -n "Setting initial stripe for test file..."
6072         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6073                 error "cannot set stripe"
6074         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6075                 error "stripe size not set"
6076         echo "done."
6077
6078         # File currently set to -S 512K -c 1
6079
6080         # Ensure -c and -S options are rejected when -R is set
6081         echo -n "Verifying incompatible options are detected..."
6082         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6083                 error "incompatible -c and -R options not detected"
6084         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6085                 error "incompatible -S and -R options not detected"
6086         echo "done."
6087
6088         # Ensure unrecognized options are passed through to 'lfs migrate'
6089         echo -n "Verifying -S option is passed through to lfs migrate..."
6090         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6091                 error "migration failed"
6092         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6093                 error "file was not restriped"
6094         echo "done."
6095
6096         # File currently set to -S 1M -c 1
6097
6098         # Ensure long options are supported
6099         echo -n "Verifying long options supported..."
6100         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6101                 error "long option without argument not supported"
6102         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6103                 error "long option with argument not supported"
6104         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6105                 error "file not restriped with --stripe-size option"
6106         echo "done."
6107
6108         # File currently set to -S 512K -c 1
6109
6110         if [ "$OSTCOUNT" -gt 1 ]; then
6111                 echo -n "Verifying explicit stripe count can be set..."
6112                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6113                         error "migrate failed"
6114                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6115                         error "file not restriped to explicit count"
6116                 echo "done."
6117         fi
6118
6119         # File currently set to -S 512K -c 1 or -S 512K -c 2
6120
6121         # Ensure parent striping is used if -R is set, and no stripe
6122         # count or size is specified
6123         echo -n "Setting stripe for parent directory..."
6124         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6125                 error "cannot set stripe"
6126         echo "done."
6127
6128         echo -n "Verifying restripe option uses parent stripe settings..."
6129         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6130                 error "migrate failed"
6131         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6132                 error "file not restriped to parent settings"
6133         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6134                 error "file not restriped to parent settings"
6135         echo "done."
6136
6137         # File currently set to -S 1M -c 1
6138
6139         # Ensure striping is preserved if -R is not set, and no stripe
6140         # count or size is specified
6141         echo -n "Verifying striping size preserved when not specified..."
6142         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6143         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6144                 error "cannot set stripe on parent directory"
6145         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6146                 error "migrate failed"
6147         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6148                 error "file was restriped"
6149         echo "done."
6150
6151         # Ensure file name properly detected when final option has no argument
6152         echo -n "Verifying file name properly detected..."
6153         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6154                 error "file name interpreted as option argument"
6155         echo "done."
6156
6157         # Clean up
6158         rm -f "$file1"
6159 }
6160 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6161
6162 test_56wd() {
6163         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6164
6165         local file1=$DIR/$tdir/file1
6166
6167         echo -n "Creating test dir..."
6168         test_mkdir $DIR/$tdir || error "cannot create dir"
6169         echo "done."
6170
6171         echo -n "Creating test file..."
6172         touch $file1
6173         echo "done."
6174
6175         # Ensure 'lfs migrate' will fail by using a non-existent option,
6176         # and make sure rsync is not called to recover
6177         echo -n "Make sure --no-rsync option works..."
6178         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6179                 grep -q 'refusing to fall back to rsync' ||
6180                 error "rsync was called with --no-rsync set"
6181         echo "done."
6182
6183         # Ensure rsync is called without trying 'lfs migrate' first
6184         echo -n "Make sure --rsync option works..."
6185         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6186                 grep -q 'falling back to rsync' &&
6187                 error "lfs migrate was called with --rsync set"
6188         echo "done."
6189
6190         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6191         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6192                 grep -q 'at the same time' ||
6193                 error "--rsync and --no-rsync accepted concurrently"
6194         echo "done."
6195
6196         # Clean up
6197         rm -f $file1
6198 }
6199 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6200
6201 test_56x() {
6202         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6203         check_swap_layouts_support
6204
6205         local dir=$DIR/$tdir
6206         local ref1=/etc/passwd
6207         local file1=$dir/file1
6208
6209         test_mkdir $dir || error "creating dir $dir"
6210         $LFS setstripe -c 2 $file1
6211         cp $ref1 $file1
6212         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6213         stripe=$($LFS getstripe -c $file1)
6214         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6215         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6216
6217         # clean up
6218         rm -f $file1
6219 }
6220 run_test 56x "lfs migration support"
6221
6222 test_56xa() {
6223         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6224         check_swap_layouts_support
6225
6226         local dir=$DIR/$tdir/$testnum
6227
6228         test_mkdir -p $dir
6229
6230         local ref1=/etc/passwd
6231         local file1=$dir/file1
6232
6233         $LFS setstripe -c 2 $file1
6234         cp $ref1 $file1
6235         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6236
6237         local stripe=$($LFS getstripe -c $file1)
6238
6239         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6240         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6241
6242         # clean up
6243         rm -f $file1
6244 }
6245 run_test 56xa "lfs migration --block support"
6246
6247 check_migrate_links() {
6248         local dir="$1"
6249         local file1="$dir/file1"
6250         local begin="$2"
6251         local count="$3"
6252         local total_count=$(($begin + $count - 1))
6253         local symlink_count=10
6254         local uniq_count=10
6255
6256         if [ ! -f "$file1" ]; then
6257                 echo -n "creating initial file..."
6258                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6259                         error "cannot setstripe initial file"
6260                 echo "done"
6261
6262                 echo -n "creating symlinks..."
6263                 for s in $(seq 1 $symlink_count); do
6264                         ln -s "$file1" "$dir/slink$s" ||
6265                                 error "cannot create symlinks"
6266                 done
6267                 echo "done"
6268
6269                 echo -n "creating nonlinked files..."
6270                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6271                         error "cannot create nonlinked files"
6272                 echo "done"
6273         fi
6274
6275         # create hard links
6276         if [ ! -f "$dir/file$total_count" ]; then
6277                 echo -n "creating hard links $begin:$total_count..."
6278                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6279                         /dev/null || error "cannot create hard links"
6280                 echo "done"
6281         fi
6282
6283         echo -n "checking number of hard links listed in xattrs..."
6284         local fid=$($LFS getstripe -F "$file1")
6285         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6286
6287         echo "${#paths[*]}"
6288         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6289                         skip "hard link list has unexpected size, skipping test"
6290         fi
6291         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6292                         error "link names should exceed xattrs size"
6293         fi
6294
6295         echo -n "migrating files..."
6296         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6297         local rc=$?
6298         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6299         echo "done"
6300
6301         # make sure all links have been properly migrated
6302         echo -n "verifying files..."
6303         fid=$($LFS getstripe -F "$file1") ||
6304                 error "cannot get fid for file $file1"
6305         for i in $(seq 2 $total_count); do
6306                 local fid2=$($LFS getstripe -F $dir/file$i)
6307
6308                 [ "$fid2" == "$fid" ] ||
6309                         error "migrated hard link has mismatched FID"
6310         done
6311
6312         # make sure hard links were properly detected, and migration was
6313         # performed only once for the entire link set; nonlinked files should
6314         # also be migrated
6315         local actual=$(grep -c 'done' <<< "$migrate_out")
6316         local expected=$(($uniq_count + 1))
6317
6318         [ "$actual" -eq  "$expected" ] ||
6319                 error "hard links individually migrated ($actual != $expected)"
6320
6321         # make sure the correct number of hard links are present
6322         local hardlinks=$(stat -c '%h' "$file1")
6323
6324         [ $hardlinks -eq $total_count ] ||
6325                 error "num hard links $hardlinks != $total_count"
6326         echo "done"
6327
6328         return 0
6329 }
6330
6331 test_56xb() {
6332         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6333                 skip "Need MDS version at least 2.10.55"
6334
6335         local dir="$DIR/$tdir"
6336
6337         test_mkdir "$dir" || error "cannot create dir $dir"
6338
6339         echo "testing lfs migrate mode when all links fit within xattrs"
6340         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6341
6342         echo "testing rsync mode when all links fit within xattrs"
6343         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6344
6345         echo "testing lfs migrate mode when all links do not fit within xattrs"
6346         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6347
6348         echo "testing rsync mode when all links do not fit within xattrs"
6349         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6350
6351
6352         # clean up
6353         rm -rf $dir
6354 }
6355 run_test 56xb "lfs migration hard link support"
6356
6357 test_56xc() {
6358         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6359
6360         local dir="$DIR/$tdir"
6361
6362         test_mkdir "$dir" || error "cannot create dir $dir"
6363
6364         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6365         echo -n "Setting initial stripe for 20MB test file..."
6366         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6367                 error "cannot setstripe 20MB file"
6368         echo "done"
6369         echo -n "Sizing 20MB test file..."
6370         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6371         echo "done"
6372         echo -n "Verifying small file autostripe count is 1..."
6373         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6374                 error "cannot migrate 20MB file"
6375         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6376                 error "cannot get stripe for $dir/20mb"
6377         [ $stripe_count -eq 1 ] ||
6378                 error "unexpected stripe count $stripe_count for 20MB file"
6379         rm -f "$dir/20mb"
6380         echo "done"
6381
6382         # Test 2: File is small enough to fit within the available space on
6383         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6384         # have at least an additional 1KB for each desired stripe for test 3
6385         echo -n "Setting stripe for 1GB test file..."
6386         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6387         echo "done"
6388         echo -n "Sizing 1GB test file..."
6389         # File size is 1GB + 3KB
6390         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6391         echo "done"
6392
6393         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6394         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6395         if (( avail > 524288 * OSTCOUNT )); then
6396                 echo -n "Migrating 1GB file..."
6397                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6398                         error "cannot migrate 1GB file"
6399                 echo "done"
6400                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6401                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6402                         error "cannot getstripe for 1GB file"
6403                 [ $stripe_count -eq 2 ] ||
6404                         error "unexpected stripe count $stripe_count != 2"
6405                 echo "done"
6406         fi
6407
6408         # Test 3: File is too large to fit within the available space on
6409         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6410         if [ $OSTCOUNT -ge 3 ]; then
6411                 # The required available space is calculated as
6412                 # file size (1GB + 3KB) / OST count (3).
6413                 local kb_per_ost=349526
6414
6415                 echo -n "Migrating 1GB file with limit..."
6416                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6417                         error "cannot migrate 1GB file with limit"
6418                 echo "done"
6419
6420                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6421                 echo -n "Verifying 1GB autostripe count with limited space..."
6422                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6423                         error "unexpected stripe count $stripe_count (min 3)"
6424                 echo "done"
6425         fi
6426
6427         # clean up
6428         rm -rf $dir
6429 }
6430 run_test 56xc "lfs migration autostripe"
6431
6432 test_56y() {
6433         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6434                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6435
6436         local res=""
6437         local dir=$DIR/$tdir
6438         local f1=$dir/file1
6439         local f2=$dir/file2
6440
6441         test_mkdir -p $dir || error "creating dir $dir"
6442         touch $f1 || error "creating std file $f1"
6443         $MULTIOP $f2 H2c || error "creating released file $f2"
6444
6445         # a directory can be raid0, so ask only for files
6446         res=$($LFS find $dir -L raid0 -type f | wc -l)
6447         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6448
6449         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6450         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6451
6452         # only files can be released, so no need to force file search
6453         res=$($LFS find $dir -L released)
6454         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6455
6456         res=$($LFS find $dir -type f \! -L released)
6457         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6458 }
6459 run_test 56y "lfs find -L raid0|released"
6460
6461 test_56z() { # LU-4824
6462         # This checks to make sure 'lfs find' continues after errors
6463         # There are two classes of errors that should be caught:
6464         # - If multiple paths are provided, all should be searched even if one
6465         #   errors out
6466         # - If errors are encountered during the search, it should not terminate
6467         #   early
6468         local dir=$DIR/$tdir
6469         local i
6470
6471         test_mkdir $dir
6472         for i in d{0..9}; do
6473                 test_mkdir $dir/$i
6474                 touch $dir/$i/$tfile
6475         done
6476         $LFS find $DIR/non_existent_dir $dir &&
6477                 error "$LFS find did not return an error"
6478         # Make a directory unsearchable. This should NOT be the last entry in
6479         # directory order.  Arbitrarily pick the 6th entry
6480         chmod 700 $($LFS find $dir -type d | sed '6!d')
6481
6482         $RUNAS $LFS find $DIR/non_existent $dir
6483         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6484
6485         # The user should be able to see 10 directories and 9 files
6486         (( count == 19 )) ||
6487                 error "$LFS find found $count != 19 entries after error"
6488 }
6489 run_test 56z "lfs find should continue after an error"
6490
6491 test_56aa() { # LU-5937
6492         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6493
6494         local dir=$DIR/$tdir
6495
6496         mkdir $dir
6497         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6498
6499         createmany -o $dir/striped_dir/${tfile}- 1024
6500         local dirs=$($LFS find --size +8k $dir/)
6501
6502         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6503 }
6504 run_test 56aa "lfs find --size under striped dir"
6505
6506 test_56ab() { # LU-10705
6507         test_mkdir $DIR/$tdir
6508         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6509         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6510         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6511         # Flush writes to ensure valid blocks.  Need to be more thorough for
6512         # ZFS, since blocks are not allocated/returned to client immediately.
6513         sync_all_data
6514         wait_zfs_commit ost1 2
6515         cancel_lru_locks osc
6516         ls -ls $DIR/$tdir
6517
6518         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6519
6520         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6521
6522         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6523         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6524
6525         rm -f $DIR/$tdir/$tfile.[123]
6526 }
6527 run_test 56ab "lfs find --blocks"
6528
6529 test_56ba() {
6530         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6531                 skip "Need MDS version at least 2.10.50"
6532
6533         # Create composite files with one component
6534         local dir=$DIR/$tdir
6535
6536         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6537         # Create composite files with three components
6538         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6539         # Create non-composite files
6540         createmany -o $dir/${tfile}- 10
6541
6542         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6543
6544         [[ $nfiles == 10 ]] ||
6545                 error "lfs find -E 1M found $nfiles != 10 files"
6546
6547         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6548         [[ $nfiles == 25 ]] ||
6549                 error "lfs find ! -E 1M found $nfiles != 25 files"
6550
6551         # All files have a component that starts at 0
6552         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6553         [[ $nfiles == 35 ]] ||
6554                 error "lfs find --component-start 0 - $nfiles != 35 files"
6555
6556         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6557         [[ $nfiles == 15 ]] ||
6558                 error "lfs find --component-start 2M - $nfiles != 15 files"
6559
6560         # All files created here have a componenet that does not starts at 2M
6561         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6562         [[ $nfiles == 35 ]] ||
6563                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6564
6565         # Find files with a specified number of components
6566         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6567         [[ $nfiles == 15 ]] ||
6568                 error "lfs find --component-count 3 - $nfiles != 15 files"
6569
6570         # Remember non-composite files have a component count of zero
6571         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6572         [[ $nfiles == 10 ]] ||
6573                 error "lfs find --component-count 0 - $nfiles != 10 files"
6574
6575         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6576         [[ $nfiles == 20 ]] ||
6577                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6578
6579         # All files have a flag called "init"
6580         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6581         [[ $nfiles == 35 ]] ||
6582                 error "lfs find --component-flags init - $nfiles != 35 files"
6583
6584         # Multi-component files will have a component not initialized
6585         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6586         [[ $nfiles == 15 ]] ||
6587                 error "lfs find !--component-flags init - $nfiles != 15 files"
6588
6589         rm -rf $dir
6590
6591 }
6592 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6593
6594 test_56ca() {
6595         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6596                 skip "Need MDS version at least 2.10.57"
6597
6598         local td=$DIR/$tdir
6599         local tf=$td/$tfile
6600         local dir
6601         local nfiles
6602         local cmd
6603         local i
6604         local j
6605
6606         # create mirrored directories and mirrored files
6607         mkdir $td || error "mkdir $td failed"
6608         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6609         createmany -o $tf- 10 || error "create $tf- failed"
6610
6611         for i in $(seq 2); do
6612                 dir=$td/dir$i
6613                 mkdir $dir || error "mkdir $dir failed"
6614                 $LFS mirror create -N$((3 + i)) $dir ||
6615                         error "create mirrored dir $dir failed"
6616                 createmany -o $dir/$tfile- 10 ||
6617                         error "create $dir/$tfile- failed"
6618         done
6619
6620         # change the states of some mirrored files
6621         echo foo > $tf-6
6622         for i in $(seq 2); do
6623                 dir=$td/dir$i
6624                 for j in $(seq 4 9); do
6625                         echo foo > $dir/$tfile-$j
6626                 done
6627         done
6628
6629         # find mirrored files with specific mirror count
6630         cmd="$LFS find --mirror-count 3 --type f $td"
6631         nfiles=$($cmd | wc -l)
6632         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6633
6634         cmd="$LFS find ! --mirror-count 3 --type f $td"
6635         nfiles=$($cmd | wc -l)
6636         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6637
6638         cmd="$LFS find --mirror-count +2 --type f $td"
6639         nfiles=$($cmd | wc -l)
6640         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6641
6642         cmd="$LFS find --mirror-count -6 --type f $td"
6643         nfiles=$($cmd | wc -l)
6644         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6645
6646         # find mirrored files with specific file state
6647         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6648         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6649
6650         cmd="$LFS find --mirror-state=ro --type f $td"
6651         nfiles=$($cmd | wc -l)
6652         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6653
6654         cmd="$LFS find ! --mirror-state=ro --type f $td"
6655         nfiles=$($cmd | wc -l)
6656         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6657
6658         cmd="$LFS find --mirror-state=wp --type f $td"
6659         nfiles=$($cmd | wc -l)
6660         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6661
6662         cmd="$LFS find ! --mirror-state=sp --type f $td"
6663         nfiles=$($cmd | wc -l)
6664         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6665 }
6666 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6667
6668 test_57a() {
6669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6670         # note test will not do anything if MDS is not local
6671         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6672                 skip_env "ldiskfs only test"
6673         fi
6674         remote_mds_nodsh && skip "remote MDS with nodsh"
6675
6676         local MNTDEV="osd*.*MDT*.mntdev"
6677         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6678         [ -z "$DEV" ] && error "can't access $MNTDEV"
6679         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6680                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6681                         error "can't access $DEV"
6682                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6683                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6684                 rm $TMP/t57a.dump
6685         done
6686 }
6687 run_test 57a "verify MDS filesystem created with large inodes =="
6688
6689 test_57b() {
6690         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6691         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6692                 skip_env "ldiskfs only test"
6693         fi
6694         remote_mds_nodsh && skip "remote MDS with nodsh"
6695
6696         local dir=$DIR/$tdir
6697         local filecount=100
6698         local file1=$dir/f1
6699         local fileN=$dir/f$filecount
6700
6701         rm -rf $dir || error "removing $dir"
6702         test_mkdir -c1 $dir
6703         local mdtidx=$($LFS getstripe -m $dir)
6704         local mdtname=MDT$(printf %04x $mdtidx)
6705         local facet=mds$((mdtidx + 1))
6706
6707         echo "mcreating $filecount files"
6708         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6709
6710         # verify that files do not have EAs yet
6711         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6712                 error "$file1 has an EA"
6713         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6714                 error "$fileN has an EA"
6715
6716         sync
6717         sleep 1
6718         df $dir  #make sure we get new statfs data
6719         local mdsfree=$(do_facet $facet \
6720                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6721         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6722         local file
6723
6724         echo "opening files to create objects/EAs"
6725         for file in $(seq -f $dir/f%g 1 $filecount); do
6726                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6727                         error "opening $file"
6728         done
6729
6730         # verify that files have EAs now
6731         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6732         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6733
6734         sleep 1  #make sure we get new statfs data
6735         df $dir
6736         local mdsfree2=$(do_facet $facet \
6737                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6738         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6739
6740         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6741                 if [ "$mdsfree" != "$mdsfree2" ]; then
6742                         error "MDC before $mdcfree != after $mdcfree2"
6743                 else
6744                         echo "MDC before $mdcfree != after $mdcfree2"
6745                         echo "unable to confirm if MDS has large inodes"
6746                 fi
6747         fi
6748         rm -rf $dir
6749 }
6750 run_test 57b "default LOV EAs are stored inside large inodes ==="
6751
6752 test_58() {
6753         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6754         [ -z "$(which wiretest 2>/dev/null)" ] &&
6755                         skip_env "could not find wiretest"
6756
6757         wiretest
6758 }
6759 run_test 58 "verify cross-platform wire constants =============="
6760
6761 test_59() {
6762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6763
6764         echo "touch 130 files"
6765         createmany -o $DIR/f59- 130
6766         echo "rm 130 files"
6767         unlinkmany $DIR/f59- 130
6768         sync
6769         # wait for commitment of removal
6770         wait_delete_completed
6771 }
6772 run_test 59 "verify cancellation of llog records async ========="
6773
6774 TEST60_HEAD="test_60 run $RANDOM"
6775 test_60a() {
6776         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6777         remote_mgs_nodsh && skip "remote MGS with nodsh"
6778         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6779                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6780                         skip_env "missing subtest run-llog.sh"
6781
6782         log "$TEST60_HEAD - from kernel mode"
6783         do_facet mgs "$LCTL dk > /dev/null"
6784         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6785         do_facet mgs $LCTL dk > $TMP/$tfile
6786
6787         # LU-6388: test llog_reader
6788         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6789         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6790         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6791                         skip_env "missing llog_reader"
6792         local fstype=$(facet_fstype mgs)
6793         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6794                 skip_env "Only for ldiskfs or zfs type mgs"
6795
6796         local mntpt=$(facet_mntpt mgs)
6797         local mgsdev=$(mgsdevname 1)
6798         local fid_list
6799         local fid
6800         local rec_list
6801         local rec
6802         local rec_type
6803         local obj_file
6804         local path
6805         local seq
6806         local oid
6807         local pass=true
6808
6809         #get fid and record list
6810         fid_list=($(awk '/9_sub.*record/ { print $NF }' /$TMP/$tfile |
6811                 tail -n 4))
6812         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' /$TMP/$tfile |
6813                 tail -n 4))
6814         #remount mgs as ldiskfs or zfs type
6815         stop mgs || error "stop mgs failed"
6816         mount_fstype mgs || error "remount mgs failed"
6817         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6818                 fid=${fid_list[i]}
6819                 rec=${rec_list[i]}
6820                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6821                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6822                 oid=$((16#$oid))
6823
6824                 case $fstype in
6825                         ldiskfs )
6826                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6827                         zfs )
6828                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6829                 esac
6830                 echo "obj_file is $obj_file"
6831                 do_facet mgs $llog_reader $obj_file
6832
6833                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6834                         awk '{ print $3 }' | sed -e "s/^type=//g")
6835                 if [ $rec_type != $rec ]; then
6836                         echo "FAILED test_60a wrong record type $rec_type," \
6837                               "should be $rec"
6838                         pass=false
6839                         break
6840                 fi
6841
6842                 #check obj path if record type is LLOG_LOGID_MAGIC
6843                 if [ "$rec" == "1064553b" ]; then
6844                         path=$(do_facet mgs $llog_reader $obj_file |
6845                                 grep "path=" | awk '{ print $NF }' |
6846                                 sed -e "s/^path=//g")
6847                         if [ $obj_file != $mntpt/$path ]; then
6848                                 echo "FAILED test_60a wrong obj path" \
6849                                       "$montpt/$path, should be $obj_file"
6850                                 pass=false
6851                                 break
6852                         fi
6853                 fi
6854         done
6855         rm -f $TMP/$tfile
6856         #restart mgs before "error", otherwise it will block the next test
6857         stop mgs || error "stop mgs failed"
6858         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6859         $pass || error "test failed, see FAILED test_60a messages for specifics"
6860 }
6861 run_test 60a "llog_test run from kernel module and test llog_reader"
6862
6863 test_60b() { # bug 6411
6864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6865
6866         dmesg > $DIR/$tfile
6867         LLOG_COUNT=$(do_facet mgs dmesg |
6868                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
6869                           /llog_[a-z]*.c:[0-9]/ {
6870                                 if (marker)
6871                                         from_marker++
6872                                 from_begin++
6873                           }
6874                           END {
6875                                 if (marker)
6876                                         print from_marker
6877                                 else
6878                                         print from_begin
6879                           }")
6880
6881         [[ $LLOG_COUNT -gt 120 ]] &&
6882                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
6883 }
6884 run_test 60b "limit repeated messages from CERROR/CWARN"
6885
6886 test_60c() {
6887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6888
6889         echo "create 5000 files"
6890         createmany -o $DIR/f60c- 5000
6891 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
6892         lctl set_param fail_loc=0x80000137
6893         unlinkmany $DIR/f60c- 5000
6894         lctl set_param fail_loc=0
6895 }
6896 run_test 60c "unlink file when mds full"
6897
6898 test_60d() {
6899         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6900
6901         SAVEPRINTK=$(lctl get_param -n printk)
6902         # verify "lctl mark" is even working"
6903         MESSAGE="test message ID $RANDOM $$"
6904         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6905         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
6906
6907         lctl set_param printk=0 || error "set lnet.printk failed"
6908         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
6909         MESSAGE="new test message ID $RANDOM $$"
6910         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
6911         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
6912         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
6913
6914         lctl set_param -n printk="$SAVEPRINTK"
6915 }
6916 run_test 60d "test printk console message masking"
6917
6918 test_60e() {
6919         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6920         remote_mds_nodsh && skip "remote MDS with nodsh"
6921
6922         touch $DIR/$tfile
6923 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
6924         do_facet mds1 lctl set_param fail_loc=0x15b
6925         rm $DIR/$tfile
6926 }
6927 run_test 60e "no space while new llog is being created"
6928
6929 test_60g() {
6930         local pid
6931
6932         test_mkdir -c $MDSCOUNT $DIR/$tdir
6933         $LFS setdirstripe -D -i -1 -c $MDSCOUNT $DIR/$tdir
6934
6935         (
6936                 local index=0
6937                 while true; do
6938                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
6939                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
6940                         index=$((index + 1))
6941                 done
6942         ) &
6943
6944         pid=$!
6945
6946         for i in $(seq 100); do 
6947                 # define OBD_FAIL_OSD_TXN_START    0x19a
6948                 do_facet mds1 lctl set_param fail_loc=0x8000019a
6949                 usleep 100
6950         done
6951
6952         kill -9 $pid
6953
6954         mkdir $DIR/$tdir/new || error "mkdir failed"
6955         rmdir $DIR/$tdir/new || error "rmdir failed"
6956 }
6957 run_test 60g "transaction abort won't cause MDT hung"
6958
6959 test_60h() {
6960         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
6961                 skip "Need MDS version at least 2.12.52"
6962         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
6963
6964         local f
6965
6966         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
6967         #define OBD_FAIL_MDS_STRIPE_FID          0x189
6968         for fail_loc in 0x80000188 0x80000189; do
6969                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
6970                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
6971                         error "mkdir $dir-$fail_loc failed"
6972                 for i in {0..10}; do
6973                         # create may fail on missing stripe
6974                         echo $i > $DIR/$tdir-$fail_loc/$i
6975                 done
6976                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6977                         error "getdirstripe $tdir-$fail_loc failed"
6978                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
6979                         error "migrate $tdir-$fail_loc failed"
6980                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
6981                         error "getdirstripe $tdir-$fail_loc failed"
6982                 pushd $DIR/$tdir-$fail_loc
6983                 for f in *; do
6984                         echo $f | cmp $f - || error "$f data mismatch"
6985                 done
6986                 popd
6987                 rm -rf $DIR/$tdir-$fail_loc
6988         done
6989 }
6990 run_test 60h "striped directory with missing stripes can be accessed"
6991
6992 test_61a() {
6993         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6994
6995         f="$DIR/f61"
6996         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
6997         cancel_lru_locks osc
6998         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
6999         sync
7000 }
7001 run_test 61a "mmap() writes don't make sync hang ================"
7002
7003 test_61b() {
7004         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7005 }
7006 run_test 61b "mmap() of unstriped file is successful"
7007
7008 # bug 2330 - insufficient obd_match error checking causes LBUG
7009 test_62() {
7010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7011
7012         f="$DIR/f62"
7013         echo foo > $f
7014         cancel_lru_locks osc
7015         lctl set_param fail_loc=0x405
7016         cat $f && error "cat succeeded, expect -EIO"
7017         lctl set_param fail_loc=0
7018 }
7019 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7020 # match every page all of the time.
7021 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7022
7023 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7024 # Though this test is irrelevant anymore, it helped to reveal some
7025 # other grant bugs (LU-4482), let's keep it.
7026 test_63a() {   # was test_63
7027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7028
7029         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7030
7031         for i in `seq 10` ; do
7032                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7033                 sleep 5
7034                 kill $!
7035                 sleep 1
7036         done
7037
7038         rm -f $DIR/f63 || true
7039 }
7040 run_test 63a "Verify oig_wait interruption does not crash ======="
7041
7042 # bug 2248 - async write errors didn't return to application on sync
7043 # bug 3677 - async write errors left page locked
7044 test_63b() {
7045         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7046
7047         debugsave
7048         lctl set_param debug=-1
7049
7050         # ensure we have a grant to do async writes
7051         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7052         rm $DIR/$tfile
7053
7054         sync    # sync lest earlier test intercept the fail_loc
7055
7056         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7057         lctl set_param fail_loc=0x80000406
7058         $MULTIOP $DIR/$tfile Owy && \
7059                 error "sync didn't return ENOMEM"
7060         sync; sleep 2; sync     # do a real sync this time to flush page
7061         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7062                 error "locked page left in cache after async error" || true
7063         debugrestore
7064 }
7065 run_test 63b "async write errors should be returned to fsync ==="
7066
7067 test_64a () {
7068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7069
7070         df $DIR
7071         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7072 }
7073 run_test 64a "verify filter grant calculations (in kernel) ====="
7074
7075 test_64b () {
7076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7077
7078         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7079 }
7080 run_test 64b "check out-of-space detection on client"
7081
7082 test_64c() {
7083         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7084 }
7085 run_test 64c "verify grant shrink"
7086
7087 # this does exactly what osc_request.c:osc_announce_cached() does in
7088 # order to calculate max amount of grants to ask from server
7089 want_grant() {
7090         local tgt=$1
7091
7092         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7093         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7094
7095         ((rpc_in_flight ++));
7096         nrpages=$((nrpages * rpc_in_flight))
7097
7098         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7099
7100         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7101
7102         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7103         local undirty=$((nrpages * PAGE_SIZE))
7104
7105         local max_extent_pages
7106         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7107             grep grant_max_extent_size | awk '{print $2}')
7108         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7109         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7110         local grant_extent_tax
7111         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7112             grep grant_extent_tax | awk '{print $2}')
7113
7114         undirty=$((undirty + nrextents * grant_extent_tax))
7115
7116         echo $undirty
7117 }
7118
7119 # this is size of unit for grant allocation. It should be equal to
7120 # what tgt_grant.c:tgt_grant_chunk() calculates
7121 grant_chunk() {
7122         local tgt=$1
7123         local max_brw_size
7124         local grant_extent_tax
7125
7126         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7127             grep max_brw_size | awk '{print $2}')
7128
7129         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7130             grep grant_extent_tax | awk '{print $2}')
7131
7132         echo $(((max_brw_size + grant_extent_tax) * 2))
7133 }
7134
7135 test_64d() {
7136         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7137                 skip "OST < 2.10.55 doesn't limit grants enough"
7138
7139         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7140         local file=$DIR/$tfile
7141
7142         [[ $($LCTL get_param osc.${tgt}.import |
7143              grep "connect_flags:.*grant_param") ]] ||
7144                 skip "no grant_param connect flag"
7145
7146         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7147
7148         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7149
7150         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7151         stack_trap "rm -f $file" EXIT
7152
7153         $LFS setstripe $file -i 0 -c 1
7154         dd if=/dev/zero of=$file bs=1M count=1000 &
7155         ddpid=$!
7156
7157         while true
7158         do
7159                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7160                 if [[ $cur_grant -gt $max_cur_granted ]]
7161                 then
7162                         kill $ddpid
7163                         error "cur_grant $cur_grant > $max_cur_granted"
7164                 fi
7165                 kill -0 $ddpid
7166                 [[ $? -ne 0 ]] && break;
7167                 sleep 2
7168         done
7169
7170         rm -f $DIR/$tfile
7171         wait_delete_completed
7172         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7173 }
7174 run_test 64d "check grant limit exceed"
7175
7176 # bug 1414 - set/get directories' stripe info
7177 test_65a() {
7178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7179
7180         test_mkdir $DIR/$tdir
7181         touch $DIR/$tdir/f1
7182         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7183 }
7184 run_test 65a "directory with no stripe info"
7185
7186 test_65b() {
7187         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7188
7189         test_mkdir $DIR/$tdir
7190         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7191
7192         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7193                                                 error "setstripe"
7194         touch $DIR/$tdir/f2
7195         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7196 }
7197 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7198
7199 test_65c() {
7200         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7201         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7202
7203         test_mkdir $DIR/$tdir
7204         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7205
7206         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7207                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7208         touch $DIR/$tdir/f3
7209         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7210 }
7211 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7212
7213 test_65d() {
7214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7215
7216         test_mkdir $DIR/$tdir
7217         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7218         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7219
7220         if [[ $STRIPECOUNT -le 0 ]]; then
7221                 sc=1
7222         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7223                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7224                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7225         else
7226                 sc=$(($STRIPECOUNT - 1))
7227         fi
7228         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7229         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7230         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7231                 error "lverify failed"
7232 }
7233 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7234
7235 test_65e() {
7236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7237
7238         test_mkdir $DIR/$tdir
7239
7240         $LFS setstripe $DIR/$tdir || error "setstripe"
7241         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7242                                         error "no stripe info failed"
7243         touch $DIR/$tdir/f6
7244         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7245 }
7246 run_test 65e "directory setstripe defaults"
7247
7248 test_65f() {
7249         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7250
7251         test_mkdir $DIR/${tdir}f
7252         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7253                 error "setstripe succeeded" || true
7254 }
7255 run_test 65f "dir setstripe permission (should return error) ==="
7256
7257 test_65g() {
7258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7259
7260         test_mkdir $DIR/$tdir
7261         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7262
7263         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7264                 error "setstripe -S failed"
7265         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7266         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7267                 error "delete default stripe failed"
7268 }
7269 run_test 65g "directory setstripe -d"
7270
7271 test_65h() {
7272         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7273
7274         test_mkdir $DIR/$tdir
7275         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7276
7277         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7278                 error "setstripe -S failed"
7279         test_mkdir $DIR/$tdir/dd1
7280         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7281                 error "stripe info inherit failed"
7282 }
7283 run_test 65h "directory stripe info inherit ===================="
7284
7285 test_65i() {
7286         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7287
7288         save_layout_restore_at_exit $MOUNT
7289
7290         # bug6367: set non-default striping on root directory
7291         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7292
7293         # bug12836: getstripe on -1 default directory striping
7294         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7295
7296         # bug12836: getstripe -v on -1 default directory striping
7297         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7298
7299         # bug12836: new find on -1 default directory striping
7300         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7301 }
7302 run_test 65i "various tests to set root directory striping"
7303
7304 test_65j() { # bug6367
7305         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7306
7307         sync; sleep 1
7308
7309         # if we aren't already remounting for each test, do so for this test
7310         if [ "$I_MOUNTED" = "yes" ]; then
7311                 cleanup || error "failed to unmount"
7312                 setup
7313         fi
7314
7315         save_layout_restore_at_exit $MOUNT
7316
7317         $LFS setstripe -d $MOUNT || error "setstripe failed"
7318 }
7319 run_test 65j "set default striping on root directory (bug 6367)="
7320
7321 cleanup_65k() {
7322         rm -rf $DIR/$tdir
7323         wait_delete_completed
7324         do_facet $SINGLEMDS "lctl set_param -n \
7325                 osp.$ost*MDT0000.max_create_count=$max_count"
7326         do_facet $SINGLEMDS "lctl set_param -n \
7327                 osp.$ost*MDT0000.create_count=$count"
7328         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7329         echo $INACTIVE_OSC "is Activate"
7330
7331         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7332 }
7333
7334 test_65k() { # bug11679
7335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7336         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7337         remote_mds_nodsh && skip "remote MDS with nodsh"
7338
7339         local disable_precreate=true
7340         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7341                 disable_precreate=false
7342
7343         echo "Check OST status: "
7344         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7345                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7346
7347         for OSC in $MDS_OSCS; do
7348                 echo $OSC "is active"
7349                 do_facet $SINGLEMDS lctl --device %$OSC activate
7350         done
7351
7352         for INACTIVE_OSC in $MDS_OSCS; do
7353                 local ost=$(osc_to_ost $INACTIVE_OSC)
7354                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7355                                lov.*md*.target_obd |
7356                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7357
7358                 mkdir -p $DIR/$tdir
7359                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7360                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7361
7362                 echo "Deactivate: " $INACTIVE_OSC
7363                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7364
7365                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7366                               osp.$ost*MDT0000.create_count")
7367                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7368                                   osp.$ost*MDT0000.max_create_count")
7369                 $disable_precreate &&
7370                         do_facet $SINGLEMDS "lctl set_param -n \
7371                                 osp.$ost*MDT0000.max_create_count=0"
7372
7373                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7374                         [ -f $DIR/$tdir/$idx ] && continue
7375                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7376                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7377                                 { cleanup_65k;
7378                                   error "setstripe $idx should succeed"; }
7379                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7380                 done
7381                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7382                 rmdir $DIR/$tdir
7383
7384                 do_facet $SINGLEMDS "lctl set_param -n \
7385                         osp.$ost*MDT0000.max_create_count=$max_count"
7386                 do_facet $SINGLEMDS "lctl set_param -n \
7387                         osp.$ost*MDT0000.create_count=$count"
7388                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7389                 echo $INACTIVE_OSC "is Activate"
7390
7391                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7392         done
7393 }
7394 run_test 65k "validate manual striping works properly with deactivated OSCs"
7395
7396 test_65l() { # bug 12836
7397         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7398
7399         test_mkdir -p $DIR/$tdir/test_dir
7400         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7401         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7402 }
7403 run_test 65l "lfs find on -1 stripe dir ========================"
7404
7405 test_65m() {
7406         local layout=$(save_layout $MOUNT)
7407         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7408                 restore_layout $MOUNT $layout
7409                 error "setstripe should fail by non-root users"
7410         }
7411         true
7412 }
7413 run_test 65m "normal user can't set filesystem default stripe"
7414
7415 test_65n() {
7416         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7417         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7418                 skip "Need MDS version at least 2.12.50"
7419         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7420
7421         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7422         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7423         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7424
7425         local root_layout=$(save_layout $MOUNT)
7426         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7427
7428         # new subdirectory under root directory should not inherit
7429         # the default layout from root
7430         local dir1=$MOUNT/$tdir-1
7431         mkdir $dir1 || error "mkdir $dir1 failed"
7432         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7433                 error "$dir1 shouldn't have LOV EA"
7434
7435         # delete the default layout on root directory
7436         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7437
7438         local dir2=$MOUNT/$tdir-2
7439         mkdir $dir2 || error "mkdir $dir2 failed"
7440         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7441                 error "$dir2 shouldn't have LOV EA"
7442
7443         # set a new striping pattern on root directory
7444         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7445         local new_def_stripe_size=$((def_stripe_size * 2))
7446         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7447                 error "set stripe size on $MOUNT failed"
7448
7449         # new file created in $dir2 should inherit the new stripe size from
7450         # the filesystem default
7451         local file2=$dir2/$tfile-2
7452         touch $file2 || error "touch $file2 failed"
7453
7454         local file2_stripe_size=$($LFS getstripe -S $file2)
7455         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7456                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7457
7458         local dir3=$MOUNT/$tdir-3
7459         mkdir $dir3 || error "mkdir $dir3 failed"
7460         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7461                 error "$dir3 shouldn't have LOV EA"
7462
7463         # set OST pool on root directory
7464         local pool=$TESTNAME
7465         pool_add $pool || error "add $pool failed"
7466         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7467                 error "add targets to $pool failed"
7468
7469         $LFS setstripe -p $pool $MOUNT ||
7470                 error "set OST pool on $MOUNT failed"
7471
7472         # new file created in $dir3 should inherit the pool from
7473         # the filesystem default
7474         local file3=$dir3/$tfile-3
7475         touch $file3 || error "touch $file3 failed"
7476
7477         local file3_pool=$($LFS getstripe -p $file3)
7478         [[ "$file3_pool" = "$pool" ]] ||
7479                 error "$file3 didn't inherit OST pool $pool"
7480
7481         local dir4=$MOUNT/$tdir-4
7482         mkdir $dir4 || error "mkdir $dir4 failed"
7483         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7484                 error "$dir4 shouldn't have LOV EA"
7485
7486         # new file created in $dir4 should inherit the pool from
7487         # the filesystem default
7488         local file4=$dir4/$tfile-4
7489         touch $file4 || error "touch $file4 failed"
7490
7491         local file4_pool=$($LFS getstripe -p $file4)
7492         [[ "$file4_pool" = "$pool" ]] ||
7493                 error "$file4 didn't inherit OST pool $pool"
7494
7495         # new subdirectory under non-root directory should inherit
7496         # the default layout from its parent directory
7497         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7498                 error "set directory layout on $dir4 failed"
7499
7500         local dir5=$dir4/$tdir-5
7501         mkdir $dir5 || error "mkdir $dir5 failed"
7502
7503         local dir4_layout=$(get_layout_param $dir4)
7504         local dir5_layout=$(get_layout_param $dir5)
7505         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7506                 error "$dir5 should inherit the default layout from $dir4"
7507 }
7508 run_test 65n "don't inherit default layout from root for new subdirectories"
7509
7510 # bug 2543 - update blocks count on client
7511 test_66() {
7512         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7513
7514         COUNT=${COUNT:-8}
7515         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7516         sync; sync_all_data; sync; sync_all_data
7517         cancel_lru_locks osc
7518         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7519         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7520 }
7521 run_test 66 "update inode blocks count on client ==============="
7522
7523 meminfo() {
7524         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7525 }
7526
7527 swap_used() {
7528         swapon -s | awk '($1 == "'$1'") { print $4 }'
7529 }
7530
7531 # bug5265, obdfilter oa2dentry return -ENOENT
7532 # #define OBD_FAIL_SRV_ENOENT 0x217
7533 test_69() {
7534         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7535         remote_ost_nodsh && skip "remote OST with nodsh"
7536
7537         f="$DIR/$tfile"
7538         $LFS setstripe -c 1 -i 0 $f
7539
7540         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7541
7542         do_facet ost1 lctl set_param fail_loc=0x217
7543         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7544         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7545
7546         do_facet ost1 lctl set_param fail_loc=0
7547         $DIRECTIO write $f 0 2 || error "write error"
7548
7549         cancel_lru_locks osc
7550         $DIRECTIO read $f 0 1 || error "read error"
7551
7552         do_facet ost1 lctl set_param fail_loc=0x217
7553         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7554
7555         do_facet ost1 lctl set_param fail_loc=0
7556         rm -f $f
7557 }
7558 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7559
7560 test_71() {
7561         test_mkdir $DIR/$tdir
7562         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7563         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7564 }
7565 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7566
7567 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7568         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7569         [ "$RUNAS_ID" = "$UID" ] &&
7570                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7571         # Check that testing environment is properly set up. Skip if not
7572         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7573                 skip_env "User $RUNAS_ID does not exist - skipping"
7574
7575         touch $DIR/$tfile
7576         chmod 777 $DIR/$tfile
7577         chmod ug+s $DIR/$tfile
7578         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7579                 error "$RUNAS dd $DIR/$tfile failed"
7580         # See if we are still setuid/sgid
7581         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7582                 error "S/gid is not dropped on write"
7583         # Now test that MDS is updated too
7584         cancel_lru_locks mdc
7585         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7586                 error "S/gid is not dropped on MDS"
7587         rm -f $DIR/$tfile
7588 }
7589 run_test 72a "Test that remove suid works properly (bug5695) ===="
7590
7591 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7592         local perm
7593
7594         [ "$RUNAS_ID" = "$UID" ] &&
7595                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7596         [ "$RUNAS_ID" -eq 0 ] &&
7597                 skip_env "RUNAS_ID = 0 -- skipping"
7598         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7599         # Check that testing environment is properly set up. Skip if not
7600         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7601                 skip_env "User $RUNAS_ID does not exist - skipping"
7602
7603         touch $DIR/${tfile}-f{g,u}
7604         test_mkdir $DIR/${tfile}-dg
7605         test_mkdir $DIR/${tfile}-du
7606         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7607         chmod g+s $DIR/${tfile}-{f,d}g
7608         chmod u+s $DIR/${tfile}-{f,d}u
7609         for perm in 777 2777 4777; do
7610                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7611                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7612                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7613                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7614         done
7615         true
7616 }
7617 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7618
7619 # bug 3462 - multiple simultaneous MDC requests
7620 test_73() {
7621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7622
7623         test_mkdir $DIR/d73-1
7624         test_mkdir $DIR/d73-2
7625         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7626         pid1=$!
7627
7628         lctl set_param fail_loc=0x80000129
7629         $MULTIOP $DIR/d73-1/f73-2 Oc &
7630         sleep 1
7631         lctl set_param fail_loc=0
7632
7633         $MULTIOP $DIR/d73-2/f73-3 Oc &
7634         pid3=$!
7635
7636         kill -USR1 $pid1
7637         wait $pid1 || return 1
7638
7639         sleep 25
7640
7641         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7642         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7643         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7644
7645         rm -rf $DIR/d73-*
7646 }
7647 run_test 73 "multiple MDC requests (should not deadlock)"
7648
7649 test_74a() { # bug 6149, 6184
7650         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7651
7652         touch $DIR/f74a
7653         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7654         #
7655         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7656         # will spin in a tight reconnection loop
7657         $LCTL set_param fail_loc=0x8000030e
7658         # get any lock that won't be difficult - lookup works.
7659         ls $DIR/f74a
7660         $LCTL set_param fail_loc=0
7661         rm -f $DIR/f74a
7662         true
7663 }
7664 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7665
7666 test_74b() { # bug 13310
7667         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7668
7669         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7670         #
7671         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7672         # will spin in a tight reconnection loop
7673         $LCTL set_param fail_loc=0x8000030e
7674         # get a "difficult" lock
7675         touch $DIR/f74b
7676         $LCTL set_param fail_loc=0
7677         rm -f $DIR/f74b
7678         true
7679 }
7680 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7681
7682 test_74c() {
7683         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7684
7685         #define OBD_FAIL_LDLM_NEW_LOCK
7686         $LCTL set_param fail_loc=0x319
7687         touch $DIR/$tfile && error "touch successful"
7688         $LCTL set_param fail_loc=0
7689         true
7690 }
7691 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7692
7693 num_inodes() {
7694         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7695 }
7696
7697 test_76() { # Now for bug 20433, added originally in bug 1443
7698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7699
7700         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7701
7702         cancel_lru_locks osc
7703         BEFORE_INODES=$(num_inodes)
7704         echo "before inodes: $BEFORE_INODES"
7705         local COUNT=1000
7706         [ "$SLOW" = "no" ] && COUNT=100
7707         for i in $(seq $COUNT); do
7708                 touch $DIR/$tfile
7709                 rm -f $DIR/$tfile
7710         done
7711         cancel_lru_locks osc
7712         AFTER_INODES=$(num_inodes)
7713         echo "after inodes: $AFTER_INODES"
7714         local wait=0
7715         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7716                 sleep 2
7717                 AFTER_INODES=$(num_inodes)
7718                 wait=$((wait+2))
7719                 echo "wait $wait seconds inodes: $AFTER_INODES"
7720                 if [ $wait -gt 30 ]; then
7721                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7722                 fi
7723         done
7724 }
7725 run_test 76 "confirm clients recycle inodes properly ===="
7726
7727
7728 export ORIG_CSUM=""
7729 set_checksums()
7730 {
7731         # Note: in sptlrpc modes which enable its own bulk checksum, the
7732         # original crc32_le bulk checksum will be automatically disabled,
7733         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7734         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7735         # In this case set_checksums() will not be no-op, because sptlrpc
7736         # bulk checksum will be enabled all through the test.
7737
7738         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7739         lctl set_param -n osc.*.checksums $1
7740         return 0
7741 }
7742
7743 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7744                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7745 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7746                              tr -d [] | head -n1)}
7747 set_checksum_type()
7748 {
7749         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7750         log "set checksum type to $1"
7751         return 0
7752 }
7753 F77_TMP=$TMP/f77-temp
7754 F77SZ=8
7755 setup_f77() {
7756         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7757                 error "error writing to $F77_TMP"
7758 }
7759
7760 test_77a() { # bug 10889
7761         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7762         $GSS && skip_env "could not run with gss"
7763
7764         [ ! -f $F77_TMP ] && setup_f77
7765         set_checksums 1
7766         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7767         set_checksums 0
7768         rm -f $DIR/$tfile
7769 }
7770 run_test 77a "normal checksum read/write operation"
7771
7772 test_77b() { # bug 10889
7773         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7774         $GSS && skip_env "could not run with gss"
7775
7776         [ ! -f $F77_TMP ] && setup_f77
7777         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7778         $LCTL set_param fail_loc=0x80000409
7779         set_checksums 1
7780
7781         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7782                 error "dd error: $?"
7783         $LCTL set_param fail_loc=0
7784
7785         for algo in $CKSUM_TYPES; do
7786                 cancel_lru_locks osc
7787                 set_checksum_type $algo
7788                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7789                 $LCTL set_param fail_loc=0x80000408
7790                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7791                 $LCTL set_param fail_loc=0
7792         done
7793         set_checksums 0
7794         set_checksum_type $ORIG_CSUM_TYPE
7795         rm -f $DIR/$tfile
7796 }
7797 run_test 77b "checksum error on client write, read"
7798
7799 cleanup_77c() {
7800         trap 0
7801         set_checksums 0
7802         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7803         $check_ost &&
7804                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7805         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7806         $check_ost && [ -n "$ost_file_prefix" ] &&
7807                 do_facet ost1 rm -f ${ost_file_prefix}\*
7808 }
7809
7810 test_77c() {
7811         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7812         $GSS && skip_env "could not run with gss"
7813         remote_ost_nodsh && skip "remote OST with nodsh"
7814
7815         local bad1
7816         local osc_file_prefix
7817         local osc_file
7818         local check_ost=false
7819         local ost_file_prefix
7820         local ost_file
7821         local orig_cksum
7822         local dump_cksum
7823         local fid
7824
7825         # ensure corruption will occur on first OSS/OST
7826         $LFS setstripe -i 0 $DIR/$tfile
7827
7828         [ ! -f $F77_TMP ] && setup_f77
7829         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7830                 error "dd write error: $?"
7831         fid=$($LFS path2fid $DIR/$tfile)
7832
7833         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
7834         then
7835                 check_ost=true
7836                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
7837                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
7838         else
7839                 echo "OSS do not support bulk pages dump upon error"
7840         fi
7841
7842         osc_file_prefix=$($LCTL get_param -n debug_path)
7843         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
7844
7845         trap cleanup_77c EXIT
7846
7847         set_checksums 1
7848         # enable bulk pages dump upon error on Client
7849         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
7850         # enable bulk pages dump upon error on OSS
7851         $check_ost &&
7852                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
7853
7854         # flush Client cache to allow next read to reach OSS
7855         cancel_lru_locks osc
7856
7857         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
7858         $LCTL set_param fail_loc=0x80000408
7859         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
7860         $LCTL set_param fail_loc=0
7861
7862         rm -f $DIR/$tfile
7863
7864         # check cksum dump on Client
7865         osc_file=$(ls ${osc_file_prefix}*)
7866         [ -n "$osc_file" ] || error "no checksum dump file on Client"
7867         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
7868         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
7869         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
7870         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
7871                      cksum)
7872         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
7873         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7874                 error "dump content does not match on Client"
7875
7876         $check_ost || skip "No need to check cksum dump on OSS"
7877
7878         # check cksum dump on OSS
7879         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
7880         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
7881         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
7882         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
7883         [[ "$orig_cksum" == "$dump_cksum" ]] ||
7884                 error "dump content does not match on OSS"
7885
7886         cleanup_77c
7887 }
7888 run_test 77c "checksum error on client read with debug"
7889
7890 test_77d() { # bug 10889
7891         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7892         $GSS && skip_env "could not run with gss"
7893
7894         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7895         $LCTL set_param fail_loc=0x80000409
7896         set_checksums 1
7897         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7898                 error "direct write: rc=$?"
7899         $LCTL set_param fail_loc=0
7900         set_checksums 0
7901
7902         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7903         $LCTL set_param fail_loc=0x80000408
7904         set_checksums 1
7905         cancel_lru_locks osc
7906         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
7907                 error "direct read: rc=$?"
7908         $LCTL set_param fail_loc=0
7909         set_checksums 0
7910 }
7911 run_test 77d "checksum error on OST direct write, read"
7912
7913 test_77f() { # bug 10889
7914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7915         $GSS && skip_env "could not run with gss"
7916
7917         set_checksums 1
7918         for algo in $CKSUM_TYPES; do
7919                 cancel_lru_locks osc
7920                 set_checksum_type $algo
7921                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7922                 $LCTL set_param fail_loc=0x409
7923                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
7924                         error "direct write succeeded"
7925                 $LCTL set_param fail_loc=0
7926         done
7927         set_checksum_type $ORIG_CSUM_TYPE
7928         set_checksums 0
7929 }
7930 run_test 77f "repeat checksum error on write (expect error)"
7931
7932 test_77g() { # bug 10889
7933         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7934         $GSS && skip_env "could not run with gss"
7935         remote_ost_nodsh && skip "remote OST with nodsh"
7936
7937         [ ! -f $F77_TMP ] && setup_f77
7938
7939         local file=$DIR/$tfile
7940         stack_trap "rm -f $file" EXIT
7941
7942         $LFS setstripe -c 1 -i 0 $file
7943         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
7944         do_facet ost1 lctl set_param fail_loc=0x8000021a
7945         set_checksums 1
7946         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
7947                 error "write error: rc=$?"
7948         do_facet ost1 lctl set_param fail_loc=0
7949         set_checksums 0
7950
7951         cancel_lru_locks osc
7952         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
7953         do_facet ost1 lctl set_param fail_loc=0x8000021b
7954         set_checksums 1
7955         cmp $F77_TMP $file || error "file compare failed"
7956         do_facet ost1 lctl set_param fail_loc=0
7957         set_checksums 0
7958 }
7959 run_test 77g "checksum error on OST write, read"
7960
7961 test_77k() { # LU-10906
7962         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7963         $GSS && skip_env "could not run with gss"
7964
7965         local cksum_param="osc.$FSNAME*.checksums"
7966         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
7967         local checksum
7968         local i
7969
7970         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
7971         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
7972         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
7973                 EXIT
7974
7975         for i in 0 1; do
7976                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
7977                         error "failed to set checksum=$i on MGS"
7978                 wait_update $HOSTNAME "$get_checksum" $i
7979                 #remount
7980                 echo "remount client, checksum should be $i"
7981                 remount_client $MOUNT || "failed to remount client"
7982                 checksum=$(eval $get_checksum)
7983                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7984         done
7985         # remove persistent param to avoid races with checksum mountopt below
7986         do_facet mgs $LCTL set_param -P -d $cksum_param ||
7987                 error "failed to delete checksum on MGS"
7988
7989         for opt in "checksum" "nochecksum"; do
7990                 #remount with mount option
7991                 echo "remount client with option $opt, checksum should be $i"
7992                 umount_client $MOUNT || "failed to umount client"
7993                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
7994                         "failed to mount client with option '$opt'"
7995                 checksum=$(eval $get_checksum)
7996                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
7997                 i=$((i - 1))
7998         done
7999
8000         remount_client $MOUNT || "failed to remount client"
8001 }
8002 run_test 77k "enable/disable checksum correctly"
8003
8004 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8005 rm -f $F77_TMP
8006 unset F77_TMP
8007
8008 cleanup_test_78() {
8009         trap 0
8010         rm -f $DIR/$tfile
8011 }
8012
8013 test_78() { # bug 10901
8014         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8015         remote_ost || skip_env "local OST"
8016
8017         NSEQ=5
8018         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8019         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8020         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8021         echo "MemTotal: $MEMTOTAL"
8022
8023         # reserve 256MB of memory for the kernel and other running processes,
8024         # and then take 1/2 of the remaining memory for the read/write buffers.
8025         if [ $MEMTOTAL -gt 512 ] ;then
8026                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8027         else
8028                 # for those poor memory-starved high-end clusters...
8029                 MEMTOTAL=$((MEMTOTAL / 2))
8030         fi
8031         echo "Mem to use for directio: $MEMTOTAL"
8032
8033         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8034         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8035         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8036         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8037                 head -n1)
8038         echo "Smallest OST: $SMALLESTOST"
8039         [[ $SMALLESTOST -lt 10240 ]] &&
8040                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8041
8042         trap cleanup_test_78 EXIT
8043
8044         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8045                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8046
8047         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8048         echo "File size: $F78SIZE"
8049         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8050         for i in $(seq 1 $NSEQ); do
8051                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8052                 echo directIO rdwr round $i of $NSEQ
8053                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8054         done
8055
8056         cleanup_test_78
8057 }
8058 run_test 78 "handle large O_DIRECT writes correctly ============"
8059
8060 test_79() { # bug 12743
8061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8062
8063         wait_delete_completed
8064
8065         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8066         BKFREE=$(calc_osc_kbytes kbytesfree)
8067         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8068
8069         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8070         DFTOTAL=`echo $STRING | cut -d, -f1`
8071         DFUSED=`echo $STRING  | cut -d, -f2`
8072         DFAVAIL=`echo $STRING | cut -d, -f3`
8073         DFFREE=$(($DFTOTAL - $DFUSED))
8074
8075         ALLOWANCE=$((64 * $OSTCOUNT))
8076
8077         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8078            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8079                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8080         fi
8081         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8082            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8083                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8084         fi
8085         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8086            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8087                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8088         fi
8089 }
8090 run_test 79 "df report consistency check ======================="
8091
8092 test_80() { # bug 10718
8093         remote_ost_nodsh && skip "remote OST with nodsh"
8094         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8095
8096         # relax strong synchronous semantics for slow backends like ZFS
8097         local soc="obdfilter.*.sync_on_lock_cancel"
8098         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8099         local hosts=
8100         if [ "$soc_old" != "never" ] &&
8101                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8102                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8103                                 facet_active_host $host; done | sort -u)
8104                         do_nodes $hosts lctl set_param $soc=never
8105         fi
8106
8107         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8108         sync; sleep 1; sync
8109         local BEFORE=`date +%s`
8110         cancel_lru_locks osc
8111         local AFTER=`date +%s`
8112         local DIFF=$((AFTER-BEFORE))
8113         if [ $DIFF -gt 1 ] ; then
8114                 error "elapsed for 1M@1T = $DIFF"
8115         fi
8116
8117         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8118
8119         rm -f $DIR/$tfile
8120 }
8121 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8122
8123 test_81a() { # LU-456
8124         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8125         remote_ost_nodsh && skip "remote OST with nodsh"
8126
8127         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8128         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8129         do_facet ost1 lctl set_param fail_loc=0x80000228
8130
8131         # write should trigger a retry and success
8132         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8133         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8134         RC=$?
8135         if [ $RC -ne 0 ] ; then
8136                 error "write should success, but failed for $RC"
8137         fi
8138 }
8139 run_test 81a "OST should retry write when get -ENOSPC ==============="
8140
8141 test_81b() { # LU-456
8142         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8143         remote_ost_nodsh && skip "remote OST with nodsh"
8144
8145         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8146         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8147         do_facet ost1 lctl set_param fail_loc=0x228
8148
8149         # write should retry several times and return -ENOSPC finally
8150         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8151         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8152         RC=$?
8153         ENOSPC=28
8154         if [ $RC -ne $ENOSPC ] ; then
8155                 error "dd should fail for -ENOSPC, but succeed."
8156         fi
8157 }
8158 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8159
8160 test_82() { # LU-1031
8161         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8162         local gid1=14091995
8163         local gid2=16022000
8164
8165         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8166         local MULTIPID1=$!
8167         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8168         local MULTIPID2=$!
8169         kill -USR1 $MULTIPID2
8170         sleep 2
8171         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8172                 error "First grouplock does not block second one"
8173         else
8174                 echo "Second grouplock blocks first one"
8175         fi
8176         kill -USR1 $MULTIPID1
8177         wait $MULTIPID1
8178         wait $MULTIPID2
8179 }
8180 run_test 82 "Basic grouplock test"
8181
8182 test_99() {
8183         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8184
8185         test_mkdir $DIR/$tdir.cvsroot
8186         chown $RUNAS_ID $DIR/$tdir.cvsroot
8187
8188         cd $TMP
8189         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8190
8191         cd /etc/init.d
8192         # some versions of cvs import exit(1) when asked to import links or
8193         # files they can't read.  ignore those files.
8194         local toignore=$(find . -type l -printf '-I %f\n' -o \
8195                          ! -perm /4 -printf '-I %f\n')
8196         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8197                 $tdir.reposname vtag rtag
8198
8199         cd $DIR
8200         test_mkdir $DIR/$tdir.reposname
8201         chown $RUNAS_ID $DIR/$tdir.reposname
8202         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8203
8204         cd $DIR/$tdir.reposname
8205         $RUNAS touch foo99
8206         $RUNAS cvs add -m 'addmsg' foo99
8207         $RUNAS cvs update
8208         $RUNAS cvs commit -m 'nomsg' foo99
8209         rm -fr $DIR/$tdir.cvsroot
8210 }
8211 run_test 99 "cvs strange file/directory operations"
8212
8213 test_100() {
8214         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8215         [[ "$NETTYPE" =~ tcp ]] ||
8216                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8217         remote_ost_nodsh && skip "remote OST with nodsh"
8218         remote_mds_nodsh && skip "remote MDS with nodsh"
8219         remote_servers ||
8220                 skip "useless for local single node setup"
8221
8222         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8223                 [ "$PROT" != "tcp" ] && continue
8224                 RPORT=$(echo $REMOTE | cut -d: -f2)
8225                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8226
8227                 rc=0
8228                 LPORT=`echo $LOCAL | cut -d: -f2`
8229                 if [ $LPORT -ge 1024 ]; then
8230                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8231                         netstat -tna
8232                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8233                 fi
8234         done
8235         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8236 }
8237 run_test 100 "check local port using privileged port ==========="
8238
8239 function get_named_value()
8240 {
8241     local tag
8242
8243     tag=$1
8244     while read ;do
8245         line=$REPLY
8246         case $line in
8247         $tag*)
8248             echo $line | sed "s/^$tag[ ]*//"
8249             break
8250             ;;
8251         esac
8252     done
8253 }
8254
8255 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8256                    awk '/^max_cached_mb/ { print $2 }')
8257
8258 cleanup_101a() {
8259         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8260         trap 0
8261 }
8262
8263 test_101a() {
8264         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8265         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8266
8267         local s
8268         local discard
8269         local nreads=10000
8270         local cache_limit=32
8271
8272         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8273         trap cleanup_101a EXIT
8274         $LCTL set_param -n llite.*.read_ahead_stats 0
8275         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8276
8277         #
8278         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8279         #
8280         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8281         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8282
8283         discard=0
8284         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8285                 get_named_value 'read but discarded' | cut -d" " -f1); do
8286                         discard=$(($discard + $s))
8287         done
8288         cleanup_101a
8289
8290         if [[ $(($discard * 10)) -gt $nreads ]]; then
8291                 $LCTL get_param osc.*-osc*.rpc_stats
8292                 $LCTL get_param llite.*.read_ahead_stats
8293                 error "too many ($discard) discarded pages"
8294         fi
8295         rm -f $DIR/$tfile || true
8296 }
8297 run_test 101a "check read-ahead for random reads"
8298
8299 setup_test101bc() {
8300         test_mkdir $DIR/$tdir
8301         local ssize=$1
8302         local FILE_LENGTH=$2
8303         STRIPE_OFFSET=0
8304
8305         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8306
8307         local list=$(comma_list $(osts_nodes))
8308         set_osd_param $list '' read_cache_enable 0
8309         set_osd_param $list '' writethrough_cache_enable 0
8310
8311         trap cleanup_test101bc EXIT
8312         # prepare the read-ahead file
8313         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8314
8315         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8316                                 count=$FILE_SIZE_MB 2> /dev/null
8317
8318 }
8319
8320 cleanup_test101bc() {
8321         trap 0
8322         rm -rf $DIR/$tdir
8323         rm -f $DIR/$tfile
8324
8325         local list=$(comma_list $(osts_nodes))
8326         set_osd_param $list '' read_cache_enable 1
8327         set_osd_param $list '' writethrough_cache_enable 1
8328 }
8329
8330 calc_total() {
8331         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8332 }
8333
8334 ra_check_101() {
8335         local READ_SIZE=$1
8336         local STRIPE_SIZE=$2
8337         local FILE_LENGTH=$3
8338         local RA_INC=1048576
8339         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8340         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8341                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8342         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8343                         get_named_value 'read but discarded' |
8344                         cut -d" " -f1 | calc_total)
8345         if [[ $DISCARD -gt $discard_limit ]]; then
8346                 $LCTL get_param llite.*.read_ahead_stats
8347                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8348         else
8349                 echo "Read-ahead success for size ${READ_SIZE}"
8350         fi
8351 }
8352
8353 test_101b() {
8354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8355         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8356
8357         local STRIPE_SIZE=1048576
8358         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8359
8360         if [ $SLOW == "yes" ]; then
8361                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8362         else
8363                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8364         fi
8365
8366         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8367
8368         # prepare the read-ahead file
8369         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8370         cancel_lru_locks osc
8371         for BIDX in 2 4 8 16 32 64 128 256
8372         do
8373                 local BSIZE=$((BIDX*4096))
8374                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8375                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8376                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8377                 $LCTL set_param -n llite.*.read_ahead_stats 0
8378                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8379                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8380                 cancel_lru_locks osc
8381                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8382         done
8383         cleanup_test101bc
8384         true
8385 }
8386 run_test 101b "check stride-io mode read-ahead ================="
8387
8388 test_101c() {
8389         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8390
8391         local STRIPE_SIZE=1048576
8392         local FILE_LENGTH=$((STRIPE_SIZE*100))
8393         local nreads=10000
8394         local rsize=65536
8395         local osc_rpc_stats
8396
8397         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8398
8399         cancel_lru_locks osc
8400         $LCTL set_param osc.*.rpc_stats 0
8401         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8402         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8403                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8404                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8405                 local size
8406
8407                 if [ $lines -le 20 ]; then
8408                         continue
8409                 fi
8410                 for size in 1 2 4 8; do
8411                         local rpc=$(echo "$stats" |
8412                                     awk '($1 == "'$size':") {print $2; exit; }')
8413                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8414                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8415                 done
8416                 echo "$osc_rpc_stats check passed!"
8417         done
8418         cleanup_test101bc
8419         true
8420 }
8421 run_test 101c "check stripe_size aligned read-ahead ================="
8422
8423 set_read_ahead() {
8424         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8425         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8426 }
8427
8428 test_101d() {
8429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8430
8431         local file=$DIR/$tfile
8432         local sz_MB=${FILESIZE_101d:-500}
8433         local ra_MB=${READAHEAD_MB:-40}
8434
8435         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8436         [ $free_MB -lt $sz_MB ] &&
8437                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8438
8439         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8440         $LFS setstripe -c -1 $file || error "setstripe failed"
8441
8442         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8443         echo Cancel LRU locks on lustre client to flush the client cache
8444         cancel_lru_locks osc
8445
8446         echo Disable read-ahead
8447         local old_READAHEAD=$(set_read_ahead 0)
8448
8449         echo Reading the test file $file with read-ahead disabled
8450         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8451
8452         echo Cancel LRU locks on lustre client to flush the client cache
8453         cancel_lru_locks osc
8454         echo Enable read-ahead with ${ra_MB}MB
8455         set_read_ahead $ra_MB
8456
8457         echo Reading the test file $file with read-ahead enabled
8458         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8459
8460         echo "read-ahead disabled time read $raOFF"
8461         echo "read-ahead enabled  time read $raON"
8462
8463         set_read_ahead $old_READAHEAD
8464         rm -f $file
8465         wait_delete_completed
8466
8467         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8468                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8469 }
8470 run_test 101d "file read with and without read-ahead enabled"
8471
8472 test_101e() {
8473         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8474
8475         local file=$DIR/$tfile
8476         local size_KB=500  #KB
8477         local count=100
8478         local bsize=1024
8479
8480         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8481         local need_KB=$((count * size_KB))
8482         [[ $free_KB -le $need_KB ]] &&
8483                 skip_env "Need free space $need_KB, have $free_KB"
8484
8485         echo "Creating $count ${size_KB}K test files"
8486         for ((i = 0; i < $count; i++)); do
8487                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8488         done
8489
8490         echo "Cancel LRU locks on lustre client to flush the client cache"
8491         cancel_lru_locks $OSC
8492
8493         echo "Reset readahead stats"
8494         $LCTL set_param -n llite.*.read_ahead_stats 0
8495
8496         for ((i = 0; i < $count; i++)); do
8497                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8498         done
8499
8500         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8501                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8502
8503         for ((i = 0; i < $count; i++)); do
8504                 rm -rf $file.$i 2>/dev/null
8505         done
8506
8507         #10000 means 20% reads are missing in readahead
8508         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8509 }
8510 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8511
8512 test_101f() {
8513         which iozone || skip_env "no iozone installed"
8514
8515         local old_debug=$($LCTL get_param debug)
8516         old_debug=${old_debug#*=}
8517         $LCTL set_param debug="reada mmap"
8518
8519         # create a test file
8520         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8521
8522         echo Cancel LRU locks on lustre client to flush the client cache
8523         cancel_lru_locks osc
8524
8525         echo Reset readahead stats
8526         $LCTL set_param -n llite.*.read_ahead_stats 0
8527
8528         echo mmap read the file with small block size
8529         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8530                 > /dev/null 2>&1
8531
8532         echo checking missing pages
8533         $LCTL get_param llite.*.read_ahead_stats
8534         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8535                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8536
8537         $LCTL set_param debug="$old_debug"
8538         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8539         rm -f $DIR/$tfile
8540 }
8541 run_test 101f "check mmap read performance"
8542
8543 test_101g_brw_size_test() {
8544         local mb=$1
8545         local pages=$((mb * 1048576 / PAGE_SIZE))
8546         local file=$DIR/$tfile
8547
8548         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8549                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8550         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8551                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8552                         return 2
8553         done
8554
8555         stack_trap "rm -f $file" EXIT
8556         $LCTL set_param -n osc.*.rpc_stats=0
8557
8558         # 10 RPCs should be enough for the test
8559         local count=10
8560         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8561                 { error "dd write ${mb} MB blocks failed"; return 3; }
8562         cancel_lru_locks osc
8563         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8564                 { error "dd write ${mb} MB blocks failed"; return 4; }
8565
8566         # calculate number of full-sized read and write RPCs
8567         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8568                 sed -n '/pages per rpc/,/^$/p' |
8569                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8570                 END { print reads,writes }'))
8571         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8572                 return 5
8573         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8574                 return 6
8575
8576         return 0
8577 }
8578
8579 test_101g() {
8580         remote_ost_nodsh && skip "remote OST with nodsh"
8581
8582         local rpcs
8583         local osts=$(get_facets OST)
8584         local list=$(comma_list $(osts_nodes))
8585         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8586         local brw_size="obdfilter.*.brw_size"
8587
8588         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8589
8590         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8591
8592         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8593                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8594                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8595            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8596                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8597                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8598
8599                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8600                         suffix="M"
8601
8602                 if [[ $orig_mb -lt 16 ]]; then
8603                         save_lustre_params $osts "$brw_size" > $p
8604                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8605                                 error "set 16MB RPC size failed"
8606
8607                         echo "remount client to enable new RPC size"
8608                         remount_client $MOUNT || error "remount_client failed"
8609                 fi
8610
8611                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8612                 # should be able to set brw_size=12, but no rpc_stats for that
8613                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8614         fi
8615
8616         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8617
8618         if [[ $orig_mb -lt 16 ]]; then
8619                 restore_lustre_params < $p
8620                 remount_client $MOUNT || error "remount_client restore failed"
8621         fi
8622
8623         rm -f $p $DIR/$tfile
8624 }
8625 run_test 101g "Big bulk(4/16 MiB) readahead"
8626
8627 test_101h() {
8628         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8629
8630         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
8631                 error "dd 70M file failed"
8632         echo Cancel LRU locks on lustre client to flush the client cache
8633         cancel_lru_locks osc
8634
8635         echo "Reset readahead stats"
8636         $LCTL set_param -n llite.*.read_ahead_stats 0
8637
8638         echo "Read 10M of data but cross 64M bundary"
8639         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
8640         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8641                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8642         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
8643         rm -f $p $DIR/$tfile
8644 }
8645 run_test 101h "Readahead should cover current read window"
8646
8647 setup_test102() {
8648         test_mkdir $DIR/$tdir
8649         chown $RUNAS_ID $DIR/$tdir
8650         STRIPE_SIZE=65536
8651         STRIPE_OFFSET=1
8652         STRIPE_COUNT=$OSTCOUNT
8653         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8654
8655         trap cleanup_test102 EXIT
8656         cd $DIR
8657         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8658         cd $DIR/$tdir
8659         for num in 1 2 3 4; do
8660                 for count in $(seq 1 $STRIPE_COUNT); do
8661                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8662                                 local size=`expr $STRIPE_SIZE \* $num`
8663                                 local file=file"$num-$idx-$count"
8664                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8665                         done
8666                 done
8667         done
8668
8669         cd $DIR
8670         $1 tar cf $TMP/f102.tar $tdir --xattrs
8671 }
8672
8673 cleanup_test102() {
8674         trap 0
8675         rm -f $TMP/f102.tar
8676         rm -rf $DIR/d0.sanity/d102
8677 }
8678
8679 test_102a() {
8680         [ "$UID" != 0 ] && skip "must run as root"
8681         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8682                 skip_env "must have user_xattr"
8683
8684         [ -z "$(which setfattr 2>/dev/null)" ] &&
8685                 skip_env "could not find setfattr"
8686
8687         local testfile=$DIR/$tfile
8688
8689         touch $testfile
8690         echo "set/get xattr..."
8691         setfattr -n trusted.name1 -v value1 $testfile ||
8692                 error "setfattr -n trusted.name1=value1 $testfile failed"
8693         getfattr -n trusted.name1 $testfile 2> /dev/null |
8694           grep "trusted.name1=.value1" ||
8695                 error "$testfile missing trusted.name1=value1"
8696
8697         setfattr -n user.author1 -v author1 $testfile ||
8698                 error "setfattr -n user.author1=author1 $testfile failed"
8699         getfattr -n user.author1 $testfile 2> /dev/null |
8700           grep "user.author1=.author1" ||
8701                 error "$testfile missing trusted.author1=author1"
8702
8703         echo "listxattr..."
8704         setfattr -n trusted.name2 -v value2 $testfile ||
8705                 error "$testfile unable to set trusted.name2"
8706         setfattr -n trusted.name3 -v value3 $testfile ||
8707                 error "$testfile unable to set trusted.name3"
8708         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8709             grep "trusted.name" | wc -l) -eq 3 ] ||
8710                 error "$testfile missing 3 trusted.name xattrs"
8711
8712         setfattr -n user.author2 -v author2 $testfile ||
8713                 error "$testfile unable to set user.author2"
8714         setfattr -n user.author3 -v author3 $testfile ||
8715                 error "$testfile unable to set user.author3"
8716         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8717             grep "user.author" | wc -l) -eq 3 ] ||
8718                 error "$testfile missing 3 user.author xattrs"
8719
8720         echo "remove xattr..."
8721         setfattr -x trusted.name1 $testfile ||
8722                 error "$testfile error deleting trusted.name1"
8723         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8724                 error "$testfile did not delete trusted.name1 xattr"
8725
8726         setfattr -x user.author1 $testfile ||
8727                 error "$testfile error deleting user.author1"
8728         echo "set lustre special xattr ..."
8729         $LFS setstripe -c1 $testfile
8730         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8731                 awk -F "=" '/trusted.lov/ { print $2 }' )
8732         setfattr -n "trusted.lov" -v $lovea $testfile ||
8733                 error "$testfile doesn't ignore setting trusted.lov again"
8734         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8735                 error "$testfile allow setting invalid trusted.lov"
8736         rm -f $testfile
8737 }
8738 run_test 102a "user xattr test =================================="
8739
8740 test_102b() {
8741         [ -z "$(which setfattr 2>/dev/null)" ] &&
8742                 skip_env "could not find setfattr"
8743         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8744
8745         # b10930: get/set/list trusted.lov xattr
8746         echo "get/set/list trusted.lov xattr ..."
8747         local testfile=$DIR/$tfile
8748         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8749                 error "setstripe failed"
8750         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8751                 error "getstripe failed"
8752         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8753                 error "can't get trusted.lov from $testfile"
8754
8755         local testfile2=${testfile}2
8756         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8757                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8758
8759         $MCREATE $testfile2
8760         setfattr -n trusted.lov -v $value $testfile2
8761         local stripe_size=$($LFS getstripe -S $testfile2)
8762         local stripe_count=$($LFS getstripe -c $testfile2)
8763         [[ $stripe_size -eq 65536 ]] ||
8764                 error "stripe size $stripe_size != 65536"
8765         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8766                 error "stripe count $stripe_count != $STRIPECOUNT"
8767         rm -f $DIR/$tfile
8768 }
8769 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8770
8771 test_102c() {
8772         [ -z "$(which setfattr 2>/dev/null)" ] &&
8773                 skip_env "could not find setfattr"
8774         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8775
8776         # b10930: get/set/list lustre.lov xattr
8777         echo "get/set/list lustre.lov xattr ..."
8778         test_mkdir $DIR/$tdir
8779         chown $RUNAS_ID $DIR/$tdir
8780         local testfile=$DIR/$tdir/$tfile
8781         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8782                 error "setstripe failed"
8783         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8784                 error "getstripe failed"
8785         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8786         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8787
8788         local testfile2=${testfile}2
8789         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8790                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8791
8792         $RUNAS $MCREATE $testfile2
8793         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8794         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8795         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
8796         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
8797         [ $stripe_count -eq $STRIPECOUNT ] ||
8798                 error "stripe count $stripe_count != $STRIPECOUNT"
8799 }
8800 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
8801
8802 compare_stripe_info1() {
8803         local stripe_index_all_zero=true
8804
8805         for num in 1 2 3 4; do
8806                 for count in $(seq 1 $STRIPE_COUNT); do
8807                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
8808                                 local size=$((STRIPE_SIZE * num))
8809                                 local file=file"$num-$offset-$count"
8810                                 stripe_size=$($LFS getstripe -S $PWD/$file)
8811                                 [[ $stripe_size -ne $size ]] &&
8812                                     error "$file: size $stripe_size != $size"
8813                                 stripe_count=$($LFS getstripe -c $PWD/$file)
8814                                 # allow fewer stripes to be created, ORI-601
8815                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
8816                                     error "$file: count $stripe_count != $count"
8817                                 stripe_index=$($LFS getstripe -i $PWD/$file)
8818                                 [[ $stripe_index -ne 0 ]] &&
8819                                         stripe_index_all_zero=false
8820                         done
8821                 done
8822         done
8823         $stripe_index_all_zero &&
8824                 error "all files are being extracted starting from OST index 0"
8825         return 0
8826 }
8827
8828 have_xattrs_include() {
8829         tar --help | grep -q xattrs-include &&
8830                 echo --xattrs-include="lustre.*"
8831 }
8832
8833 test_102d() {
8834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8835         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8836
8837         XINC=$(have_xattrs_include)
8838         setup_test102
8839         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8840         cd $DIR/$tdir/$tdir
8841         compare_stripe_info1
8842 }
8843 run_test 102d "tar restore stripe info from tarfile,not keep osts"
8844
8845 test_102f() {
8846         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8847         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8848
8849         XINC=$(have_xattrs_include)
8850         setup_test102
8851         test_mkdir $DIR/$tdir.restore
8852         cd $DIR
8853         tar cf - --xattrs $tdir | tar xf - \
8854                 -C $DIR/$tdir.restore --xattrs $XINC
8855         cd $DIR/$tdir.restore/$tdir
8856         compare_stripe_info1
8857 }
8858 run_test 102f "tar copy files, not keep osts"
8859
8860 grow_xattr() {
8861         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
8862                 skip "must have user_xattr"
8863         [ -z "$(which setfattr 2>/dev/null)" ] &&
8864                 skip_env "could not find setfattr"
8865         [ -z "$(which getfattr 2>/dev/null)" ] &&
8866                 skip_env "could not find getfattr"
8867
8868         local xsize=${1:-1024}  # in bytes
8869         local file=$DIR/$tfile
8870         local value="$(generate_string $xsize)"
8871         local xbig=trusted.big
8872         local toobig=$2
8873
8874         touch $file
8875         log "save $xbig on $file"
8876         if [ -z "$toobig" ]
8877         then
8878                 setfattr -n $xbig -v $value $file ||
8879                         error "saving $xbig on $file failed"
8880         else
8881                 setfattr -n $xbig -v $value $file &&
8882                         error "saving $xbig on $file succeeded"
8883                 return 0
8884         fi
8885
8886         local orig=$(get_xattr_value $xbig $file)
8887         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
8888
8889         local xsml=trusted.sml
8890         log "save $xsml on $file"
8891         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
8892
8893         local new=$(get_xattr_value $xbig $file)
8894         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
8895
8896         log "grow $xsml on $file"
8897         setfattr -n $xsml -v "$value" $file ||
8898                 error "growing $xsml on $file failed"
8899
8900         new=$(get_xattr_value $xbig $file)
8901         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
8902         log "$xbig still valid after growing $xsml"
8903
8904         rm -f $file
8905 }
8906
8907 test_102h() { # bug 15777
8908         grow_xattr 1024
8909 }
8910 run_test 102h "grow xattr from inside inode to external block"
8911
8912 test_102ha() {
8913         large_xattr_enabled || skip_env "ea_inode feature disabled"
8914
8915         echo "setting xattr of max xattr size: $(max_xattr_size)"
8916         grow_xattr $(max_xattr_size)
8917
8918         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
8919         echo "This should fail:"
8920         grow_xattr $(($(max_xattr_size) + 10)) 1
8921 }
8922 run_test 102ha "grow xattr from inside inode to external inode"
8923
8924 test_102i() { # bug 17038
8925         [ -z "$(which getfattr 2>/dev/null)" ] &&
8926                 skip "could not find getfattr"
8927
8928         touch $DIR/$tfile
8929         ln -s $DIR/$tfile $DIR/${tfile}link
8930         getfattr -n trusted.lov $DIR/$tfile ||
8931                 error "lgetxattr on $DIR/$tfile failed"
8932         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
8933                 grep -i "no such attr" ||
8934                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
8935         rm -f $DIR/$tfile $DIR/${tfile}link
8936 }
8937 run_test 102i "lgetxattr test on symbolic link ============"
8938
8939 test_102j() {
8940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8941         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8942
8943         XINC=$(have_xattrs_include)
8944         setup_test102 "$RUNAS"
8945         chown $RUNAS_ID $DIR/$tdir
8946         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
8947         cd $DIR/$tdir/$tdir
8948         compare_stripe_info1 "$RUNAS"
8949 }
8950 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
8951
8952 test_102k() {
8953         [ -z "$(which setfattr 2>/dev/null)" ] &&
8954                 skip "could not find setfattr"
8955
8956         touch $DIR/$tfile
8957         # b22187 just check that does not crash for regular file.
8958         setfattr -n trusted.lov $DIR/$tfile
8959         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
8960         local test_kdir=$DIR/$tdir
8961         test_mkdir $test_kdir
8962         local default_size=$($LFS getstripe -S $test_kdir)
8963         local default_count=$($LFS getstripe -c $test_kdir)
8964         local default_offset=$($LFS getstripe -i $test_kdir)
8965         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
8966                 error 'dir setstripe failed'
8967         setfattr -n trusted.lov $test_kdir
8968         local stripe_size=$($LFS getstripe -S $test_kdir)
8969         local stripe_count=$($LFS getstripe -c $test_kdir)
8970         local stripe_offset=$($LFS getstripe -i $test_kdir)
8971         [ $stripe_size -eq $default_size ] ||
8972                 error "stripe size $stripe_size != $default_size"
8973         [ $stripe_count -eq $default_count ] ||
8974                 error "stripe count $stripe_count != $default_count"
8975         [ $stripe_offset -eq $default_offset ] ||
8976                 error "stripe offset $stripe_offset != $default_offset"
8977         rm -rf $DIR/$tfile $test_kdir
8978 }
8979 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
8980
8981 test_102l() {
8982         [ -z "$(which getfattr 2>/dev/null)" ] &&
8983                 skip "could not find getfattr"
8984
8985         # LU-532 trusted. xattr is invisible to non-root
8986         local testfile=$DIR/$tfile
8987
8988         touch $testfile
8989
8990         echo "listxattr as user..."
8991         chown $RUNAS_ID $testfile
8992         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
8993             grep -q "trusted" &&
8994                 error "$testfile trusted xattrs are user visible"
8995
8996         return 0;
8997 }
8998 run_test 102l "listxattr size test =================================="
8999
9000 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9001         local path=$DIR/$tfile
9002         touch $path
9003
9004         listxattr_size_check $path || error "listattr_size_check $path failed"
9005 }
9006 run_test 102m "Ensure listxattr fails on small bufffer ========"
9007
9008 cleanup_test102
9009
9010 getxattr() { # getxattr path name
9011         # Return the base64 encoding of the value of xattr name on path.
9012         local path=$1
9013         local name=$2
9014
9015         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9016         # file: $path
9017         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9018         #
9019         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9020
9021         getfattr --absolute-names --encoding=base64 --name=$name $path |
9022                 awk -F= -v name=$name '$1 == name {
9023                         print substr($0, index($0, "=") + 1);
9024         }'
9025 }
9026
9027 test_102n() { # LU-4101 mdt: protect internal xattrs
9028         [ -z "$(which setfattr 2>/dev/null)" ] &&
9029                 skip "could not find setfattr"
9030         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9031         then
9032                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9033         fi
9034
9035         local file0=$DIR/$tfile.0
9036         local file1=$DIR/$tfile.1
9037         local xattr0=$TMP/$tfile.0
9038         local xattr1=$TMP/$tfile.1
9039         local namelist="lov lma lmv link fid version som hsm"
9040         local name
9041         local value
9042
9043         rm -rf $file0 $file1 $xattr0 $xattr1
9044         touch $file0 $file1
9045
9046         # Get 'before' xattrs of $file1.
9047         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9048
9049         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9050                 namelist+=" lfsck_namespace"
9051         for name in $namelist; do
9052                 # Try to copy xattr from $file0 to $file1.
9053                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9054
9055                 setfattr --name=trusted.$name --value="$value" $file1 ||
9056                         error "setxattr 'trusted.$name' failed"
9057
9058                 # Try to set a garbage xattr.
9059                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9060
9061                 if [[ x$name == "xlov" ]]; then
9062                         setfattr --name=trusted.lov --value="$value" $file1 &&
9063                         error "setxattr invalid 'trusted.lov' success"
9064                 else
9065                         setfattr --name=trusted.$name --value="$value" $file1 ||
9066                                 error "setxattr invalid 'trusted.$name' failed"
9067                 fi
9068
9069                 # Try to remove the xattr from $file1. We don't care if this
9070                 # appears to succeed or fail, we just don't want there to be
9071                 # any changes or crashes.
9072                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9073         done
9074
9075         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9076         then
9077                 name="lfsck_ns"
9078                 # Try to copy xattr from $file0 to $file1.
9079                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9080
9081                 setfattr --name=trusted.$name --value="$value" $file1 ||
9082                         error "setxattr 'trusted.$name' failed"
9083
9084                 # Try to set a garbage xattr.
9085                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9086
9087                 setfattr --name=trusted.$name --value="$value" $file1 ||
9088                         error "setxattr 'trusted.$name' failed"
9089
9090                 # Try to remove the xattr from $file1. We don't care if this
9091                 # appears to succeed or fail, we just don't want there to be
9092                 # any changes or crashes.
9093                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9094         fi
9095
9096         # Get 'after' xattrs of file1.
9097         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9098
9099         if ! diff $xattr0 $xattr1; then
9100                 error "before and after xattrs of '$file1' differ"
9101         fi
9102
9103         rm -rf $file0 $file1 $xattr0 $xattr1
9104
9105         return 0
9106 }
9107 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9108
9109 test_102p() { # LU-4703 setxattr did not check ownership
9110         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9111                 skip "MDS needs to be at least 2.5.56"
9112
9113         local testfile=$DIR/$tfile
9114
9115         touch $testfile
9116
9117         echo "setfacl as user..."
9118         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9119         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9120
9121         echo "setfattr as user..."
9122         setfacl -m "u:$RUNAS_ID:---" $testfile
9123         $RUNAS setfattr -x system.posix_acl_access $testfile
9124         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9125 }
9126 run_test 102p "check setxattr(2) correctly fails without permission"
9127
9128 test_102q() {
9129         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9130                 skip "MDS needs to be at least 2.6.92"
9131
9132         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9133 }
9134 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9135
9136 test_102r() {
9137         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9138                 skip "MDS needs to be at least 2.6.93"
9139
9140         touch $DIR/$tfile || error "touch"
9141         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9142         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9143         rm $DIR/$tfile || error "rm"
9144
9145         #normal directory
9146         mkdir -p $DIR/$tdir || error "mkdir"
9147         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9148         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9149         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9150                 error "$testfile error deleting user.author1"
9151         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9152                 grep "user.$(basename $tdir)" &&
9153                 error "$tdir did not delete user.$(basename $tdir)"
9154         rmdir $DIR/$tdir || error "rmdir"
9155
9156         #striped directory
9157         test_mkdir $DIR/$tdir
9158         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9159         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9160         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9161                 error "$testfile error deleting user.author1"
9162         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9163                 grep "user.$(basename $tdir)" &&
9164                 error "$tdir did not delete user.$(basename $tdir)"
9165         rmdir $DIR/$tdir || error "rm striped dir"
9166 }
9167 run_test 102r "set EAs with empty values"
9168
9169 test_102s() {
9170         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9171                 skip "MDS needs to be at least 2.11.52"
9172
9173         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9174
9175         save_lustre_params client "llite.*.xattr_cache" > $save
9176
9177         for cache in 0 1; do
9178                 lctl set_param llite.*.xattr_cache=$cache
9179
9180                 rm -f $DIR/$tfile
9181                 touch $DIR/$tfile || error "touch"
9182                 for prefix in lustre security system trusted user; do
9183                         # Note getxattr() may fail with 'Operation not
9184                         # supported' or 'No such attribute' depending
9185                         # on prefix and cache.
9186                         getfattr -n $prefix.n102s $DIR/$tfile &&
9187                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9188                 done
9189         done
9190
9191         restore_lustre_params < $save
9192 }
9193 run_test 102s "getting nonexistent xattrs should fail"
9194
9195 test_102t() {
9196         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9197                 skip "MDS needs to be at least 2.11.52"
9198
9199         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9200
9201         save_lustre_params client "llite.*.xattr_cache" > $save
9202
9203         for cache in 0 1; do
9204                 lctl set_param llite.*.xattr_cache=$cache
9205
9206                 for buf_size in 0 256; do
9207                         rm -f $DIR/$tfile
9208                         touch $DIR/$tfile || error "touch"
9209                         setfattr -n user.multiop $DIR/$tfile
9210                         $MULTIOP $DIR/$tfile oa$buf_size ||
9211                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9212                 done
9213         done
9214
9215         restore_lustre_params < $save
9216 }
9217 run_test 102t "zero length xattr values handled correctly"
9218
9219 run_acl_subtest()
9220 {
9221     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9222     return $?
9223 }
9224
9225 test_103a() {
9226         [ "$UID" != 0 ] && skip "must run as root"
9227         $GSS && skip_env "could not run under gss"
9228         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9229                 skip_env "must have acl enabled"
9230         [ -z "$(which setfacl 2>/dev/null)" ] &&
9231                 skip_env "could not find setfacl"
9232         remote_mds_nodsh && skip "remote MDS with nodsh"
9233
9234         gpasswd -a daemon bin                           # LU-5641
9235         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9236
9237         declare -a identity_old
9238
9239         for num in $(seq $MDSCOUNT); do
9240                 switch_identity $num true || identity_old[$num]=$?
9241         done
9242
9243         SAVE_UMASK=$(umask)
9244         umask 0022
9245         mkdir -p $DIR/$tdir
9246         cd $DIR/$tdir
9247
9248         echo "performing cp ..."
9249         run_acl_subtest cp || error "run_acl_subtest cp failed"
9250         echo "performing getfacl-noacl..."
9251         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9252         echo "performing misc..."
9253         run_acl_subtest misc || error  "misc test failed"
9254         echo "performing permissions..."
9255         run_acl_subtest permissions || error "permissions failed"
9256         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9257         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9258                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9259                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9260         then
9261                 echo "performing permissions xattr..."
9262                 run_acl_subtest permissions_xattr ||
9263                         error "permissions_xattr failed"
9264         fi
9265         echo "performing setfacl..."
9266         run_acl_subtest setfacl || error  "setfacl test failed"
9267
9268         # inheritance test got from HP
9269         echo "performing inheritance..."
9270         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9271         chmod +x make-tree || error "chmod +x failed"
9272         run_acl_subtest inheritance || error "inheritance test failed"
9273         rm -f make-tree
9274
9275         echo "LU-974 ignore umask when acl is enabled..."
9276         run_acl_subtest 974 || error "LU-974 umask test failed"
9277         if [ $MDSCOUNT -ge 2 ]; then
9278                 run_acl_subtest 974_remote ||
9279                         error "LU-974 umask test failed under remote dir"
9280         fi
9281
9282         echo "LU-2561 newly created file is same size as directory..."
9283         if [ "$mds1_FSTYPE" != "zfs" ]; then
9284                 run_acl_subtest 2561 || error "LU-2561 test failed"
9285         else
9286                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9287         fi
9288
9289         run_acl_subtest 4924 || error "LU-4924 test failed"
9290
9291         cd $SAVE_PWD
9292         umask $SAVE_UMASK
9293
9294         for num in $(seq $MDSCOUNT); do
9295                 if [ "${identity_old[$num]}" = 1 ]; then
9296                         switch_identity $num false || identity_old[$num]=$?
9297                 fi
9298         done
9299 }
9300 run_test 103a "acl test"
9301
9302 test_103b() {
9303         declare -a pids
9304         local U
9305
9306         for U in {0..511}; do
9307                 {
9308                 local O=$(printf "%04o" $U)
9309
9310                 umask $(printf "%04o" $((511 ^ $O)))
9311                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9312                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9313
9314                 (( $S == ($O & 0666) )) ||
9315                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9316
9317                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9318                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9319                 (( $S == ($O & 0666) )) ||
9320                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9321
9322                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9323                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9324                 (( $S == ($O & 0666) )) ||
9325                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9326                 rm -f $DIR/$tfile.[smp]$0
9327                 } &
9328                 local pid=$!
9329
9330                 # limit the concurrently running threads to 64. LU-11878
9331                 local idx=$((U % 64))
9332                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9333                 pids[idx]=$pid
9334         done
9335         wait
9336 }
9337 run_test 103b "umask lfs setstripe"
9338
9339 test_103c() {
9340         mkdir -p $DIR/$tdir
9341         cp -rp $DIR/$tdir $DIR/$tdir.bak
9342
9343         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9344                 error "$DIR/$tdir shouldn't contain default ACL"
9345         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9346                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9347         true
9348 }
9349 run_test 103c "'cp -rp' won't set empty acl"
9350
9351 test_104a() {
9352         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9353
9354         touch $DIR/$tfile
9355         lfs df || error "lfs df failed"
9356         lfs df -ih || error "lfs df -ih failed"
9357         lfs df -h $DIR || error "lfs df -h $DIR failed"
9358         lfs df -i $DIR || error "lfs df -i $DIR failed"
9359         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9360         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9361
9362         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9363         lctl --device %$OSC deactivate
9364         lfs df || error "lfs df with deactivated OSC failed"
9365         lctl --device %$OSC activate
9366         # wait the osc back to normal
9367         wait_osc_import_ready client ost
9368
9369         lfs df || error "lfs df with reactivated OSC failed"
9370         rm -f $DIR/$tfile
9371 }
9372 run_test 104a "lfs df [-ih] [path] test ========================="
9373
9374 test_104b() {
9375         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9376         [ $RUNAS_ID -eq $UID ] &&
9377                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9378
9379         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9380                         grep "Permission denied" | wc -l)))
9381         if [ $denied_cnt -ne 0 ]; then
9382                 error "lfs check servers test failed"
9383         fi
9384 }
9385 run_test 104b "$RUNAS lfs check servers test ===================="
9386
9387 test_105a() {
9388         # doesn't work on 2.4 kernels
9389         touch $DIR/$tfile
9390         if $(flock_is_enabled); then
9391                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9392         else
9393                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9394         fi
9395         rm -f $DIR/$tfile
9396 }
9397 run_test 105a "flock when mounted without -o flock test ========"
9398
9399 test_105b() {
9400         touch $DIR/$tfile
9401         if $(flock_is_enabled); then
9402                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9403         else
9404                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9405         fi
9406         rm -f $DIR/$tfile
9407 }
9408 run_test 105b "fcntl when mounted without -o flock test ========"
9409
9410 test_105c() {
9411         touch $DIR/$tfile
9412         if $(flock_is_enabled); then
9413                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9414         else
9415                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9416         fi
9417         rm -f $DIR/$tfile
9418 }
9419 run_test 105c "lockf when mounted without -o flock test"
9420
9421 test_105d() { # bug 15924
9422         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9423
9424         test_mkdir $DIR/$tdir
9425         flock_is_enabled || skip_env "mount w/o flock enabled"
9426         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9427         $LCTL set_param fail_loc=0x80000315
9428         flocks_test 2 $DIR/$tdir
9429 }
9430 run_test 105d "flock race (should not freeze) ========"
9431
9432 test_105e() { # bug 22660 && 22040
9433         flock_is_enabled || skip_env "mount w/o flock enabled"
9434
9435         touch $DIR/$tfile
9436         flocks_test 3 $DIR/$tfile
9437 }
9438 run_test 105e "Two conflicting flocks from same process"
9439
9440 test_106() { #bug 10921
9441         test_mkdir $DIR/$tdir
9442         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9443         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9444 }
9445 run_test 106 "attempt exec of dir followed by chown of that dir"
9446
9447 test_107() {
9448         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9449
9450         CDIR=`pwd`
9451         local file=core
9452
9453         cd $DIR
9454         rm -f $file
9455
9456         local save_pattern=$(sysctl -n kernel.core_pattern)
9457         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9458         sysctl -w kernel.core_pattern=$file
9459         sysctl -w kernel.core_uses_pid=0
9460
9461         ulimit -c unlimited
9462         sleep 60 &
9463         SLEEPPID=$!
9464
9465         sleep 1
9466
9467         kill -s 11 $SLEEPPID
9468         wait $SLEEPPID
9469         if [ -e $file ]; then
9470                 size=`stat -c%s $file`
9471                 [ $size -eq 0 ] && error "Fail to create core file $file"
9472         else
9473                 error "Fail to create core file $file"
9474         fi
9475         rm -f $file
9476         sysctl -w kernel.core_pattern=$save_pattern
9477         sysctl -w kernel.core_uses_pid=$save_uses_pid
9478         cd $CDIR
9479 }
9480 run_test 107 "Coredump on SIG"
9481
9482 test_110() {
9483         test_mkdir $DIR/$tdir
9484         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9485         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9486                 error "mkdir with 256 char should fail, but did not"
9487         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9488                 error "create with 255 char failed"
9489         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9490                 error "create with 256 char should fail, but did not"
9491
9492         ls -l $DIR/$tdir
9493         rm -rf $DIR/$tdir
9494 }
9495 run_test 110 "filename length checking"
9496
9497 #
9498 # Purpose: To verify dynamic thread (OSS) creation.
9499 #
9500 test_115() {
9501         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9502         remote_ost_nodsh && skip "remote OST with nodsh"
9503
9504         # Lustre does not stop service threads once they are started.
9505         # Reset number of running threads to default.
9506         stopall
9507         setupall
9508
9509         local OSTIO_pre
9510         local save_params="$TMP/sanity-$TESTNAME.parameters"
9511
9512         # Get ll_ost_io count before I/O
9513         OSTIO_pre=$(do_facet ost1 \
9514                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9515         # Exit if lustre is not running (ll_ost_io not running).
9516         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9517
9518         echo "Starting with $OSTIO_pre threads"
9519         local thread_max=$((OSTIO_pre * 2))
9520         local rpc_in_flight=$((thread_max * 2))
9521         # Number of I/O Process proposed to be started.
9522         local nfiles
9523         local facets=$(get_facets OST)
9524
9525         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9526         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9527
9528         # Set in_flight to $rpc_in_flight
9529         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9530                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9531         nfiles=${rpc_in_flight}
9532         # Set ost thread_max to $thread_max
9533         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9534
9535         # 5 Minutes should be sufficient for max number of OSS
9536         # threads(thread_max) to be created.
9537         local timeout=300
9538
9539         # Start I/O.
9540         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9541         test_mkdir $DIR/$tdir
9542         for i in $(seq $nfiles); do
9543                 local file=$DIR/$tdir/${tfile}-$i
9544                 $LFS setstripe -c -1 -i 0 $file
9545                 ($WTL $file $timeout)&
9546         done
9547
9548         # I/O Started - Wait for thread_started to reach thread_max or report
9549         # error if thread_started is more than thread_max.
9550         echo "Waiting for thread_started to reach thread_max"
9551         local thread_started=0
9552         local end_time=$((SECONDS + timeout))
9553
9554         while [ $SECONDS -le $end_time ] ; do
9555                 echo -n "."
9556                 # Get ost i/o thread_started count.
9557                 thread_started=$(do_facet ost1 \
9558                         "$LCTL get_param \
9559                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9560                 # Break out if thread_started is equal/greater than thread_max
9561                 if [[ $thread_started -ge $thread_max ]]; then
9562                         echo ll_ost_io thread_started $thread_started, \
9563                                 equal/greater than thread_max $thread_max
9564                         break
9565                 fi
9566                 sleep 1
9567         done
9568
9569         # Cleanup - We have the numbers, Kill i/o jobs if running.
9570         jobcount=($(jobs -p))
9571         for i in $(seq 0 $((${#jobcount[@]}-1)))
9572         do
9573                 kill -9 ${jobcount[$i]}
9574                 if [ $? -ne 0 ] ; then
9575                         echo Warning: \
9576                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9577                 fi
9578         done
9579
9580         # Cleanup files left by WTL binary.
9581         for i in $(seq $nfiles); do
9582                 local file=$DIR/$tdir/${tfile}-$i
9583                 rm -rf $file
9584                 if [ $? -ne 0 ] ; then
9585                         echo "Warning: Failed to delete file $file"
9586                 fi
9587         done
9588
9589         restore_lustre_params <$save_params
9590         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9591
9592         # Error out if no new thread has started or Thread started is greater
9593         # than thread max.
9594         if [[ $thread_started -le $OSTIO_pre ||
9595                         $thread_started -gt $thread_max ]]; then
9596                 error "ll_ost_io: thread_started $thread_started" \
9597                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9598                       "No new thread started or thread started greater " \
9599                       "than thread_max."
9600         fi
9601 }
9602 run_test 115 "verify dynamic thread creation===================="
9603
9604 free_min_max () {
9605         wait_delete_completed
9606         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9607         echo "OST kbytes available: ${AVAIL[@]}"
9608         MAXV=${AVAIL[0]}
9609         MAXI=0
9610         MINV=${AVAIL[0]}
9611         MINI=0
9612         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9613                 #echo OST $i: ${AVAIL[i]}kb
9614                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9615                         MAXV=${AVAIL[i]}
9616                         MAXI=$i
9617                 fi
9618                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9619                         MINV=${AVAIL[i]}
9620                         MINI=$i
9621                 fi
9622         done
9623         echo "Min free space: OST $MINI: $MINV"
9624         echo "Max free space: OST $MAXI: $MAXV"
9625 }
9626
9627 test_116a() { # was previously test_116()
9628         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9629         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9630         remote_mds_nodsh && skip "remote MDS with nodsh"
9631
9632         echo -n "Free space priority "
9633         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9634                 head -n1
9635         declare -a AVAIL
9636         free_min_max
9637
9638         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9639         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9640         trap simple_cleanup_common EXIT
9641
9642         # Check if we need to generate uneven OSTs
9643         test_mkdir -p $DIR/$tdir/OST${MINI}
9644         local FILL=$((MINV / 4))
9645         local DIFF=$((MAXV - MINV))
9646         local DIFF2=$((DIFF * 100 / MINV))
9647
9648         local threshold=$(do_facet $SINGLEMDS \
9649                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9650         threshold=${threshold%%%}
9651         echo -n "Check for uneven OSTs: "
9652         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9653
9654         if [[ $DIFF2 -gt $threshold ]]; then
9655                 echo "ok"
9656                 echo "Don't need to fill OST$MINI"
9657         else
9658                 # generate uneven OSTs. Write 2% over the QOS threshold value
9659                 echo "no"
9660                 DIFF=$((threshold - DIFF2 + 2))
9661                 DIFF2=$((MINV * DIFF / 100))
9662                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9663                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9664                         error "setstripe failed"
9665                 DIFF=$((DIFF2 / 2048))
9666                 i=0
9667                 while [ $i -lt $DIFF ]; do
9668                         i=$((i + 1))
9669                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9670                                 bs=2M count=1 2>/dev/null
9671                         echo -n .
9672                 done
9673                 echo .
9674                 sync
9675                 sleep_maxage
9676                 free_min_max
9677         fi
9678
9679         DIFF=$((MAXV - MINV))
9680         DIFF2=$((DIFF * 100 / MINV))
9681         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9682         if [ $DIFF2 -gt $threshold ]; then
9683                 echo "ok"
9684         else
9685                 echo "failed - QOS mode won't be used"
9686                 simple_cleanup_common
9687                 skip "QOS imbalance criteria not met"
9688         fi
9689
9690         MINI1=$MINI
9691         MINV1=$MINV
9692         MAXI1=$MAXI
9693         MAXV1=$MAXV
9694
9695         # now fill using QOS
9696         $LFS setstripe -c 1 $DIR/$tdir
9697         FILL=$((FILL / 200))
9698         if [ $FILL -gt 600 ]; then
9699                 FILL=600
9700         fi
9701         echo "writing $FILL files to QOS-assigned OSTs"
9702         i=0
9703         while [ $i -lt $FILL ]; do
9704                 i=$((i + 1))
9705                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9706                         count=1 2>/dev/null
9707                 echo -n .
9708         done
9709         echo "wrote $i 200k files"
9710         sync
9711         sleep_maxage
9712
9713         echo "Note: free space may not be updated, so measurements might be off"
9714         free_min_max
9715         DIFF2=$((MAXV - MINV))
9716         echo "free space delta: orig $DIFF final $DIFF2"
9717         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9718         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9719         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9720         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9721         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9722         if [[ $DIFF -gt 0 ]]; then
9723                 FILL=$((DIFF2 * 100 / DIFF - 100))
9724                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9725         fi
9726
9727         # Figure out which files were written where
9728         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9729                awk '/'$MINI1': / {print $2; exit}')
9730         echo $UUID
9731         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9732         echo "$MINC files created on smaller OST $MINI1"
9733         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9734                awk '/'$MAXI1': / {print $2; exit}')
9735         echo $UUID
9736         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9737         echo "$MAXC files created on larger OST $MAXI1"
9738         if [[ $MINC -gt 0 ]]; then
9739                 FILL=$((MAXC * 100 / MINC - 100))
9740                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9741         fi
9742         [[ $MAXC -gt $MINC ]] ||
9743                 error_ignore LU-9 "stripe QOS didn't balance free space"
9744         simple_cleanup_common
9745 }
9746 run_test 116a "stripe QOS: free space balance ==================="
9747
9748 test_116b() { # LU-2093
9749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9750         remote_mds_nodsh && skip "remote MDS with nodsh"
9751
9752 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9753         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9754                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9755         [ -z "$old_rr" ] && skip "no QOS"
9756         do_facet $SINGLEMDS lctl set_param \
9757                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9758         mkdir -p $DIR/$tdir
9759         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9760         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9761         do_facet $SINGLEMDS lctl set_param fail_loc=0
9762         rm -rf $DIR/$tdir
9763         do_facet $SINGLEMDS lctl set_param \
9764                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9765 }
9766 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9767
9768 test_117() # bug 10891
9769 {
9770         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9771
9772         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9773         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9774         lctl set_param fail_loc=0x21e
9775         > $DIR/$tfile || error "truncate failed"
9776         lctl set_param fail_loc=0
9777         echo "Truncate succeeded."
9778         rm -f $DIR/$tfile
9779 }
9780 run_test 117 "verify osd extend =========="
9781
9782 NO_SLOW_RESENDCOUNT=4
9783 export OLD_RESENDCOUNT=""
9784 set_resend_count () {
9785         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9786         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9787         lctl set_param -n $PROC_RESENDCOUNT $1
9788         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9789 }
9790
9791 # for reduce test_118* time (b=14842)
9792 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9793
9794 # Reset async IO behavior after error case
9795 reset_async() {
9796         FILE=$DIR/reset_async
9797
9798         # Ensure all OSCs are cleared
9799         $LFS setstripe -c -1 $FILE
9800         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
9801         sync
9802         rm $FILE
9803 }
9804
9805 test_118a() #bug 11710
9806 {
9807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9808
9809         reset_async
9810
9811         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9812         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9813         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
9814
9815         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9816                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9817                 return 1;
9818         fi
9819         rm -f $DIR/$tfile
9820 }
9821 run_test 118a "verify O_SYNC works =========="
9822
9823 test_118b()
9824 {
9825         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9826         remote_ost_nodsh && skip "remote OST with nodsh"
9827
9828         reset_async
9829
9830         #define OBD_FAIL_SRV_ENOENT 0x217
9831         set_nodes_failloc "$(osts_nodes)" 0x217
9832         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9833         RC=$?
9834         set_nodes_failloc "$(osts_nodes)" 0
9835         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9836         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9837                     grep -c writeback)
9838
9839         if [[ $RC -eq 0 ]]; then
9840                 error "Must return error due to dropped pages, rc=$RC"
9841                 return 1;
9842         fi
9843
9844         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9845                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9846                 return 1;
9847         fi
9848
9849         echo "Dirty pages not leaked on ENOENT"
9850
9851         # Due to the above error the OSC will issue all RPCs syncronously
9852         # until a subsequent RPC completes successfully without error.
9853         $MULTIOP $DIR/$tfile Ow4096yc
9854         rm -f $DIR/$tfile
9855
9856         return 0
9857 }
9858 run_test 118b "Reclaim dirty pages on fatal error =========="
9859
9860 test_118c()
9861 {
9862         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9863
9864         # for 118c, restore the original resend count, LU-1940
9865         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
9866                                 set_resend_count $OLD_RESENDCOUNT
9867         remote_ost_nodsh && skip "remote OST with nodsh"
9868
9869         reset_async
9870
9871         #define OBD_FAIL_OST_EROFS               0x216
9872         set_nodes_failloc "$(osts_nodes)" 0x216
9873
9874         # multiop should block due to fsync until pages are written
9875         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9876         MULTIPID=$!
9877         sleep 1
9878
9879         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9880                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9881         fi
9882
9883         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9884                     grep -c writeback)
9885         if [[ $WRITEBACK -eq 0 ]]; then
9886                 error "No page in writeback, writeback=$WRITEBACK"
9887         fi
9888
9889         set_nodes_failloc "$(osts_nodes)" 0
9890         wait $MULTIPID
9891         RC=$?
9892         if [[ $RC -ne 0 ]]; then
9893                 error "Multiop fsync failed, rc=$RC"
9894         fi
9895
9896         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9897         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9898                     grep -c writeback)
9899         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9900                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9901         fi
9902
9903         rm -f $DIR/$tfile
9904         echo "Dirty pages flushed via fsync on EROFS"
9905         return 0
9906 }
9907 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
9908
9909 # continue to use small resend count to reduce test_118* time (b=14842)
9910 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9911
9912 test_118d()
9913 {
9914         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9915         remote_ost_nodsh && skip "remote OST with nodsh"
9916
9917         reset_async
9918
9919         #define OBD_FAIL_OST_BRW_PAUSE_BULK
9920         set_nodes_failloc "$(osts_nodes)" 0x214
9921         # multiop should block due to fsync until pages are written
9922         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
9923         MULTIPID=$!
9924         sleep 1
9925
9926         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
9927                 error "Multiop failed to block on fsync, pid=$MULTIPID"
9928         fi
9929
9930         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9931                     grep -c writeback)
9932         if [[ $WRITEBACK -eq 0 ]]; then
9933                 error "No page in writeback, writeback=$WRITEBACK"
9934         fi
9935
9936         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
9937         set_nodes_failloc "$(osts_nodes)" 0
9938
9939         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9940         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9941                     grep -c writeback)
9942         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9943                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9944         fi
9945
9946         rm -f $DIR/$tfile
9947         echo "Dirty pages gaurenteed flushed via fsync"
9948         return 0
9949 }
9950 run_test 118d "Fsync validation inject a delay of the bulk =========="
9951
9952 test_118f() {
9953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9954
9955         reset_async
9956
9957         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
9958         lctl set_param fail_loc=0x8000040a
9959
9960         # Should simulate EINVAL error which is fatal
9961         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9962         RC=$?
9963         if [[ $RC -eq 0 ]]; then
9964                 error "Must return error due to dropped pages, rc=$RC"
9965         fi
9966
9967         lctl set_param fail_loc=0x0
9968
9969         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
9970         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
9971         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
9972                     grep -c writeback)
9973         if [[ $LOCKED -ne 0 ]]; then
9974                 error "Locked pages remain in cache, locked=$LOCKED"
9975         fi
9976
9977         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
9978                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
9979         fi
9980
9981         rm -f $DIR/$tfile
9982         echo "No pages locked after fsync"
9983
9984         reset_async
9985         return 0
9986 }
9987 run_test 118f "Simulate unrecoverable OSC side error =========="
9988
9989 test_118g() {
9990         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9991
9992         reset_async
9993
9994         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
9995         lctl set_param fail_loc=0x406
9996
9997         # simulate local -ENOMEM
9998         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
9999         RC=$?
10000
10001         lctl set_param fail_loc=0
10002         if [[ $RC -eq 0 ]]; then
10003                 error "Must return error due to dropped pages, rc=$RC"
10004         fi
10005
10006         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10007         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10008         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10009                         grep -c writeback)
10010         if [[ $LOCKED -ne 0 ]]; then
10011                 error "Locked pages remain in cache, locked=$LOCKED"
10012         fi
10013
10014         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10015                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10016         fi
10017
10018         rm -f $DIR/$tfile
10019         echo "No pages locked after fsync"
10020
10021         reset_async
10022         return 0
10023 }
10024 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10025
10026 test_118h() {
10027         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10028         remote_ost_nodsh && skip "remote OST with nodsh"
10029
10030         reset_async
10031
10032         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10033         set_nodes_failloc "$(osts_nodes)" 0x20e
10034         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10035         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10036         RC=$?
10037
10038         set_nodes_failloc "$(osts_nodes)" 0
10039         if [[ $RC -eq 0 ]]; then
10040                 error "Must return error due to dropped pages, rc=$RC"
10041         fi
10042
10043         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10044         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10045         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10046                     grep -c writeback)
10047         if [[ $LOCKED -ne 0 ]]; then
10048                 error "Locked pages remain in cache, locked=$LOCKED"
10049         fi
10050
10051         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10052                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10053         fi
10054
10055         rm -f $DIR/$tfile
10056         echo "No pages locked after fsync"
10057
10058         return 0
10059 }
10060 run_test 118h "Verify timeout in handling recoverables errors  =========="
10061
10062 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10063
10064 test_118i() {
10065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10066         remote_ost_nodsh && skip "remote OST with nodsh"
10067
10068         reset_async
10069
10070         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10071         set_nodes_failloc "$(osts_nodes)" 0x20e
10072
10073         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10074         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10075         PID=$!
10076         sleep 5
10077         set_nodes_failloc "$(osts_nodes)" 0
10078
10079         wait $PID
10080         RC=$?
10081         if [[ $RC -ne 0 ]]; then
10082                 error "got error, but should be not, rc=$RC"
10083         fi
10084
10085         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10086         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10087         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10088         if [[ $LOCKED -ne 0 ]]; then
10089                 error "Locked pages remain in cache, locked=$LOCKED"
10090         fi
10091
10092         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10093                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10094         fi
10095
10096         rm -f $DIR/$tfile
10097         echo "No pages locked after fsync"
10098
10099         return 0
10100 }
10101 run_test 118i "Fix error before timeout in recoverable error  =========="
10102
10103 [ "$SLOW" = "no" ] && set_resend_count 4
10104
10105 test_118j() {
10106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10107         remote_ost_nodsh && skip "remote OST with nodsh"
10108
10109         reset_async
10110
10111         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10112         set_nodes_failloc "$(osts_nodes)" 0x220
10113
10114         # return -EIO from OST
10115         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10116         RC=$?
10117         set_nodes_failloc "$(osts_nodes)" 0x0
10118         if [[ $RC -eq 0 ]]; then
10119                 error "Must return error due to dropped pages, rc=$RC"
10120         fi
10121
10122         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10123         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10124         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10125         if [[ $LOCKED -ne 0 ]]; then
10126                 error "Locked pages remain in cache, locked=$LOCKED"
10127         fi
10128
10129         # in recoverable error on OST we want resend and stay until it finished
10130         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10131                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10132         fi
10133
10134         rm -f $DIR/$tfile
10135         echo "No pages locked after fsync"
10136
10137         return 0
10138 }
10139 run_test 118j "Simulate unrecoverable OST side error =========="
10140
10141 test_118k()
10142 {
10143         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10144         remote_ost_nodsh && skip "remote OSTs with nodsh"
10145
10146         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10147         set_nodes_failloc "$(osts_nodes)" 0x20e
10148         test_mkdir $DIR/$tdir
10149
10150         for ((i=0;i<10;i++)); do
10151                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10152                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10153                 SLEEPPID=$!
10154                 sleep 0.500s
10155                 kill $SLEEPPID
10156                 wait $SLEEPPID
10157         done
10158
10159         set_nodes_failloc "$(osts_nodes)" 0
10160         rm -rf $DIR/$tdir
10161 }
10162 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10163
10164 test_118l() # LU-646
10165 {
10166         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10167
10168         test_mkdir $DIR/$tdir
10169         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10170         rm -rf $DIR/$tdir
10171 }
10172 run_test 118l "fsync dir"
10173
10174 test_118m() # LU-3066
10175 {
10176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10177
10178         test_mkdir $DIR/$tdir
10179         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10180         rm -rf $DIR/$tdir
10181 }
10182 run_test 118m "fdatasync dir ========="
10183
10184 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10185
10186 test_118n()
10187 {
10188         local begin
10189         local end
10190
10191         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10192         remote_ost_nodsh && skip "remote OSTs with nodsh"
10193
10194         # Sleep to avoid a cached response.
10195         #define OBD_STATFS_CACHE_SECONDS 1
10196         sleep 2
10197
10198         # Inject a 10 second delay in the OST_STATFS handler.
10199         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10200         set_nodes_failloc "$(osts_nodes)" 0x242
10201
10202         begin=$SECONDS
10203         stat --file-system $MOUNT > /dev/null
10204         end=$SECONDS
10205
10206         set_nodes_failloc "$(osts_nodes)" 0
10207
10208         if ((end - begin > 20)); then
10209             error "statfs took $((end - begin)) seconds, expected 10"
10210         fi
10211 }
10212 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10213
10214 test_119a() # bug 11737
10215 {
10216         BSIZE=$((512 * 1024))
10217         directio write $DIR/$tfile 0 1 $BSIZE
10218         # We ask to read two blocks, which is more than a file size.
10219         # directio will indicate an error when requested and actual
10220         # sizes aren't equeal (a normal situation in this case) and
10221         # print actual read amount.
10222         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10223         if [ "$NOB" != "$BSIZE" ]; then
10224                 error "read $NOB bytes instead of $BSIZE"
10225         fi
10226         rm -f $DIR/$tfile
10227 }
10228 run_test 119a "Short directIO read must return actual read amount"
10229
10230 test_119b() # bug 11737
10231 {
10232         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10233
10234         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10235         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10236         sync
10237         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10238                 error "direct read failed"
10239         rm -f $DIR/$tfile
10240 }
10241 run_test 119b "Sparse directIO read must return actual read amount"
10242
10243 test_119c() # bug 13099
10244 {
10245         BSIZE=1048576
10246         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10247         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10248         rm -f $DIR/$tfile
10249 }
10250 run_test 119c "Testing for direct read hitting hole"
10251
10252 test_119d() # bug 15950
10253 {
10254         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10255
10256         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10257         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10258         BSIZE=1048576
10259         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10260         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10261         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10262         lctl set_param fail_loc=0x40d
10263         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10264         pid_dio=$!
10265         sleep 1
10266         cat $DIR/$tfile > /dev/null &
10267         lctl set_param fail_loc=0
10268         pid_reads=$!
10269         wait $pid_dio
10270         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10271         sleep 2
10272         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10273         error "the read rpcs have not completed in 2s"
10274         rm -f $DIR/$tfile
10275         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10276 }
10277 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10278
10279 test_120a() {
10280         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10281         remote_mds_nodsh && skip "remote MDS with nodsh"
10282         test_mkdir -i0 -c1 $DIR/$tdir
10283         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10284                 skip_env "no early lock cancel on server"
10285
10286         lru_resize_disable mdc
10287         lru_resize_disable osc
10288         cancel_lru_locks mdc
10289         # asynchronous object destroy at MDT could cause bl ast to client
10290         cancel_lru_locks osc
10291
10292         stat $DIR/$tdir > /dev/null
10293         can1=$(do_facet mds1 \
10294                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10295                awk '/ldlm_cancel/ {print $2}')
10296         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10297                awk '/ldlm_bl_callback/ {print $2}')
10298         test_mkdir -i0 -c1 $DIR/$tdir/d1
10299         can2=$(do_facet mds1 \
10300                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10301                awk '/ldlm_cancel/ {print $2}')
10302         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10303                awk '/ldlm_bl_callback/ {print $2}')
10304         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10305         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10306         lru_resize_enable mdc
10307         lru_resize_enable osc
10308 }
10309 run_test 120a "Early Lock Cancel: mkdir test"
10310
10311 test_120b() {
10312         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10313         remote_mds_nodsh && skip "remote MDS with nodsh"
10314         test_mkdir $DIR/$tdir
10315         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10316                 skip_env "no early lock cancel on server"
10317
10318         lru_resize_disable mdc
10319         lru_resize_disable osc
10320         cancel_lru_locks mdc
10321         stat $DIR/$tdir > /dev/null
10322         can1=$(do_facet $SINGLEMDS \
10323                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10324                awk '/ldlm_cancel/ {print $2}')
10325         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10326                awk '/ldlm_bl_callback/ {print $2}')
10327         touch $DIR/$tdir/f1
10328         can2=$(do_facet $SINGLEMDS \
10329                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10330                awk '/ldlm_cancel/ {print $2}')
10331         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10332                awk '/ldlm_bl_callback/ {print $2}')
10333         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10334         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10335         lru_resize_enable mdc
10336         lru_resize_enable osc
10337 }
10338 run_test 120b "Early Lock Cancel: create test"
10339
10340 test_120c() {
10341         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10342         remote_mds_nodsh && skip "remote MDS with nodsh"
10343         test_mkdir -i0 -c1 $DIR/$tdir
10344         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10345                 skip "no early lock cancel on server"
10346
10347         lru_resize_disable mdc
10348         lru_resize_disable osc
10349         test_mkdir -i0 -c1 $DIR/$tdir/d1
10350         test_mkdir -i0 -c1 $DIR/$tdir/d2
10351         touch $DIR/$tdir/d1/f1
10352         cancel_lru_locks mdc
10353         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10354         can1=$(do_facet mds1 \
10355                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10356                awk '/ldlm_cancel/ {print $2}')
10357         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10358                awk '/ldlm_bl_callback/ {print $2}')
10359         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10360         can2=$(do_facet mds1 \
10361                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10362                awk '/ldlm_cancel/ {print $2}')
10363         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10364                awk '/ldlm_bl_callback/ {print $2}')
10365         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10366         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10367         lru_resize_enable mdc
10368         lru_resize_enable osc
10369 }
10370 run_test 120c "Early Lock Cancel: link test"
10371
10372 test_120d() {
10373         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10374         remote_mds_nodsh && skip "remote MDS with nodsh"
10375         test_mkdir -i0 -c1 $DIR/$tdir
10376         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10377                 skip_env "no early lock cancel on server"
10378
10379         lru_resize_disable mdc
10380         lru_resize_disable osc
10381         touch $DIR/$tdir
10382         cancel_lru_locks mdc
10383         stat $DIR/$tdir > /dev/null
10384         can1=$(do_facet mds1 \
10385                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10386                awk '/ldlm_cancel/ {print $2}')
10387         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10388                awk '/ldlm_bl_callback/ {print $2}')
10389         chmod a+x $DIR/$tdir
10390         can2=$(do_facet mds1 \
10391                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10392                awk '/ldlm_cancel/ {print $2}')
10393         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10394                awk '/ldlm_bl_callback/ {print $2}')
10395         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10396         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10397         lru_resize_enable mdc
10398         lru_resize_enable osc
10399 }
10400 run_test 120d "Early Lock Cancel: setattr test"
10401
10402 test_120e() {
10403         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10404         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10405                 skip_env "no early lock cancel on server"
10406         remote_mds_nodsh && skip "remote MDS with nodsh"
10407
10408         local dlmtrace_set=false
10409
10410         test_mkdir -i0 -c1 $DIR/$tdir
10411         lru_resize_disable mdc
10412         lru_resize_disable osc
10413         ! $LCTL get_param debug | grep -q dlmtrace &&
10414                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10415         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10416         cancel_lru_locks mdc
10417         cancel_lru_locks osc
10418         dd if=$DIR/$tdir/f1 of=/dev/null
10419         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10420         # XXX client can not do early lock cancel of OST lock
10421         # during unlink (LU-4206), so cancel osc lock now.
10422         sleep 2
10423         cancel_lru_locks osc
10424         can1=$(do_facet mds1 \
10425                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10426                awk '/ldlm_cancel/ {print $2}')
10427         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10428                awk '/ldlm_bl_callback/ {print $2}')
10429         unlink $DIR/$tdir/f1
10430         sleep 5
10431         can2=$(do_facet mds1 \
10432                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10433                awk '/ldlm_cancel/ {print $2}')
10434         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10435                awk '/ldlm_bl_callback/ {print $2}')
10436         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10437                 $LCTL dk $TMP/cancel.debug.txt
10438         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10439                 $LCTL dk $TMP/blocking.debug.txt
10440         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10441         lru_resize_enable mdc
10442         lru_resize_enable osc
10443 }
10444 run_test 120e "Early Lock Cancel: unlink test"
10445
10446 test_120f() {
10447         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10448         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10449                 skip_env "no early lock cancel on server"
10450         remote_mds_nodsh && skip "remote MDS with nodsh"
10451
10452         test_mkdir -i0 -c1 $DIR/$tdir
10453         lru_resize_disable mdc
10454         lru_resize_disable osc
10455         test_mkdir -i0 -c1 $DIR/$tdir/d1
10456         test_mkdir -i0 -c1 $DIR/$tdir/d2
10457         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10458         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10459         cancel_lru_locks mdc
10460         cancel_lru_locks osc
10461         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10462         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10463         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10464         # XXX client can not do early lock cancel of OST lock
10465         # during rename (LU-4206), so cancel osc lock now.
10466         sleep 2
10467         cancel_lru_locks osc
10468         can1=$(do_facet mds1 \
10469                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10470                awk '/ldlm_cancel/ {print $2}')
10471         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10472                awk '/ldlm_bl_callback/ {print $2}')
10473         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10474         sleep 5
10475         can2=$(do_facet mds1 \
10476                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10477                awk '/ldlm_cancel/ {print $2}')
10478         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10479                awk '/ldlm_bl_callback/ {print $2}')
10480         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10481         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10482         lru_resize_enable mdc
10483         lru_resize_enable osc
10484 }
10485 run_test 120f "Early Lock Cancel: rename test"
10486
10487 test_120g() {
10488         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10489         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10490                 skip_env "no early lock cancel on server"
10491         remote_mds_nodsh && skip "remote MDS with nodsh"
10492
10493         lru_resize_disable mdc
10494         lru_resize_disable osc
10495         count=10000
10496         echo create $count files
10497         test_mkdir $DIR/$tdir
10498         cancel_lru_locks mdc
10499         cancel_lru_locks osc
10500         t0=$(date +%s)
10501
10502         can0=$(do_facet $SINGLEMDS \
10503                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10504                awk '/ldlm_cancel/ {print $2}')
10505         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10506                awk '/ldlm_bl_callback/ {print $2}')
10507         createmany -o $DIR/$tdir/f $count
10508         sync
10509         can1=$(do_facet $SINGLEMDS \
10510                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10511                awk '/ldlm_cancel/ {print $2}')
10512         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10513                awk '/ldlm_bl_callback/ {print $2}')
10514         t1=$(date +%s)
10515         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10516         echo rm $count files
10517         rm -r $DIR/$tdir
10518         sync
10519         can2=$(do_facet $SINGLEMDS \
10520                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10521                awk '/ldlm_cancel/ {print $2}')
10522         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10523                awk '/ldlm_bl_callback/ {print $2}')
10524         t2=$(date +%s)
10525         echo total: $count removes in $((t2-t1))
10526         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10527         sleep 2
10528         # wait for commitment of removal
10529         lru_resize_enable mdc
10530         lru_resize_enable osc
10531 }
10532 run_test 120g "Early Lock Cancel: performance test"
10533
10534 test_121() { #bug #10589
10535         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10536
10537         rm -rf $DIR/$tfile
10538         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10539 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10540         lctl set_param fail_loc=0x310
10541         cancel_lru_locks osc > /dev/null
10542         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10543         lctl set_param fail_loc=0
10544         [[ $reads -eq $writes ]] ||
10545                 error "read $reads blocks, must be $writes blocks"
10546 }
10547 run_test 121 "read cancel race ========="
10548
10549 test_123a() { # was test 123, statahead(bug 11401)
10550         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10551
10552         SLOWOK=0
10553         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10554                 log "testing UP system. Performance may be lower than expected."
10555                 SLOWOK=1
10556         fi
10557
10558         rm -rf $DIR/$tdir
10559         test_mkdir $DIR/$tdir
10560         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10561         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10562         MULT=10
10563         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10564                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10565
10566                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10567                 lctl set_param -n llite.*.statahead_max 0
10568                 lctl get_param llite.*.statahead_max
10569                 cancel_lru_locks mdc
10570                 cancel_lru_locks osc
10571                 stime=`date +%s`
10572                 time ls -l $DIR/$tdir | wc -l
10573                 etime=`date +%s`
10574                 delta=$((etime - stime))
10575                 log "ls $i files without statahead: $delta sec"
10576                 lctl set_param llite.*.statahead_max=$max
10577
10578                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10579                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10580                 cancel_lru_locks mdc
10581                 cancel_lru_locks osc
10582                 stime=`date +%s`
10583                 time ls -l $DIR/$tdir | wc -l
10584                 etime=`date +%s`
10585                 delta_sa=$((etime - stime))
10586                 log "ls $i files with statahead: $delta_sa sec"
10587                 lctl get_param -n llite.*.statahead_stats
10588                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10589
10590                 [[ $swrong -lt $ewrong ]] &&
10591                         log "statahead was stopped, maybe too many locks held!"
10592                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10593
10594                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10595                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10596                     lctl set_param -n llite.*.statahead_max 0
10597                     lctl get_param llite.*.statahead_max
10598                     cancel_lru_locks mdc
10599                     cancel_lru_locks osc
10600                     stime=`date +%s`
10601                     time ls -l $DIR/$tdir | wc -l
10602                     etime=`date +%s`
10603                     delta=$((etime - stime))
10604                     log "ls $i files again without statahead: $delta sec"
10605                     lctl set_param llite.*.statahead_max=$max
10606                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10607                         if [  $SLOWOK -eq 0 ]; then
10608                                 error "ls $i files is slower with statahead!"
10609                         else
10610                                 log "ls $i files is slower with statahead!"
10611                         fi
10612                         break
10613                     fi
10614                 fi
10615
10616                 [ $delta -gt 20 ] && break
10617                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10618                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10619         done
10620         log "ls done"
10621
10622         stime=`date +%s`
10623         rm -r $DIR/$tdir
10624         sync
10625         etime=`date +%s`
10626         delta=$((etime - stime))
10627         log "rm -r $DIR/$tdir/: $delta seconds"
10628         log "rm done"
10629         lctl get_param -n llite.*.statahead_stats
10630 }
10631 run_test 123a "verify statahead work"
10632
10633 test_123b () { # statahead(bug 15027)
10634         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10635
10636         test_mkdir $DIR/$tdir
10637         createmany -o $DIR/$tdir/$tfile-%d 1000
10638
10639         cancel_lru_locks mdc
10640         cancel_lru_locks osc
10641
10642 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10643         lctl set_param fail_loc=0x80000803
10644         ls -lR $DIR/$tdir > /dev/null
10645         log "ls done"
10646         lctl set_param fail_loc=0x0
10647         lctl get_param -n llite.*.statahead_stats
10648         rm -r $DIR/$tdir
10649         sync
10650
10651 }
10652 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10653
10654 test_124a() {
10655         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10656         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10657                 skip_env "no lru resize on server"
10658
10659         local NR=2000
10660
10661         test_mkdir $DIR/$tdir
10662
10663         log "create $NR files at $DIR/$tdir"
10664         createmany -o $DIR/$tdir/f $NR ||
10665                 error "failed to create $NR files in $DIR/$tdir"
10666
10667         cancel_lru_locks mdc
10668         ls -l $DIR/$tdir > /dev/null
10669
10670         local NSDIR=""
10671         local LRU_SIZE=0
10672         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10673                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10674                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10675                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10676                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10677                         log "NSDIR=$NSDIR"
10678                         log "NS=$(basename $NSDIR)"
10679                         break
10680                 fi
10681         done
10682
10683         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10684                 skip "Not enough cached locks created!"
10685         fi
10686         log "LRU=$LRU_SIZE"
10687
10688         local SLEEP=30
10689
10690         # We know that lru resize allows one client to hold $LIMIT locks
10691         # for 10h. After that locks begin to be killed by client.
10692         local MAX_HRS=10
10693         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10694         log "LIMIT=$LIMIT"
10695         if [ $LIMIT -lt $LRU_SIZE ]; then
10696                 skip "Limit is too small $LIMIT"
10697         fi
10698
10699         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10700         # killing locks. Some time was spent for creating locks. This means
10701         # that up to the moment of sleep finish we must have killed some of
10702         # them (10-100 locks). This depends on how fast ther were created.
10703         # Many of them were touched in almost the same moment and thus will
10704         # be killed in groups.
10705         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10706
10707         # Use $LRU_SIZE_B here to take into account real number of locks
10708         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10709         local LRU_SIZE_B=$LRU_SIZE
10710         log "LVF=$LVF"
10711         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10712         log "OLD_LVF=$OLD_LVF"
10713         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10714
10715         # Let's make sure that we really have some margin. Client checks
10716         # cached locks every 10 sec.
10717         SLEEP=$((SLEEP+20))
10718         log "Sleep ${SLEEP} sec"
10719         local SEC=0
10720         while ((SEC<$SLEEP)); do
10721                 echo -n "..."
10722                 sleep 5
10723                 SEC=$((SEC+5))
10724                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10725                 echo -n "$LRU_SIZE"
10726         done
10727         echo ""
10728         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10729         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10730
10731         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10732                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10733                 unlinkmany $DIR/$tdir/f $NR
10734                 return
10735         }
10736
10737         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10738         log "unlink $NR files at $DIR/$tdir"
10739         unlinkmany $DIR/$tdir/f $NR
10740 }
10741 run_test 124a "lru resize ======================================="
10742
10743 get_max_pool_limit()
10744 {
10745         local limit=$($LCTL get_param \
10746                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10747         local max=0
10748         for l in $limit; do
10749                 if [[ $l -gt $max ]]; then
10750                         max=$l
10751                 fi
10752         done
10753         echo $max
10754 }
10755
10756 test_124b() {
10757         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10758         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10759                 skip_env "no lru resize on server"
10760
10761         LIMIT=$(get_max_pool_limit)
10762
10763         NR=$(($(default_lru_size)*20))
10764         if [[ $NR -gt $LIMIT ]]; then
10765                 log "Limit lock number by $LIMIT locks"
10766                 NR=$LIMIT
10767         fi
10768
10769         IFree=$(mdsrate_inodes_available)
10770         if [ $IFree -lt $NR ]; then
10771                 log "Limit lock number by $IFree inodes"
10772                 NR=$IFree
10773         fi
10774
10775         lru_resize_disable mdc
10776         test_mkdir -p $DIR/$tdir/disable_lru_resize
10777
10778         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10779         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10780         cancel_lru_locks mdc
10781         stime=`date +%s`
10782         PID=""
10783         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10784         PID="$PID $!"
10785         sleep 2
10786         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10787         PID="$PID $!"
10788         sleep 2
10789         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10790         PID="$PID $!"
10791         wait $PID
10792         etime=`date +%s`
10793         nolruresize_delta=$((etime-stime))
10794         log "ls -la time: $nolruresize_delta seconds"
10795         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10796         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
10797
10798         lru_resize_enable mdc
10799         test_mkdir -p $DIR/$tdir/enable_lru_resize
10800
10801         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
10802         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
10803         cancel_lru_locks mdc
10804         stime=`date +%s`
10805         PID=""
10806         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10807         PID="$PID $!"
10808         sleep 2
10809         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10810         PID="$PID $!"
10811         sleep 2
10812         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
10813         PID="$PID $!"
10814         wait $PID
10815         etime=`date +%s`
10816         lruresize_delta=$((etime-stime))
10817         log "ls -la time: $lruresize_delta seconds"
10818         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
10819
10820         if [ $lruresize_delta -gt $nolruresize_delta ]; then
10821                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
10822         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
10823                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
10824         else
10825                 log "lru resize performs the same with no lru resize"
10826         fi
10827         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
10828 }
10829 run_test 124b "lru resize (performance test) ======================="
10830
10831 test_124c() {
10832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10833         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10834                 skip_env "no lru resize on server"
10835
10836         # cache ununsed locks on client
10837         local nr=100
10838         cancel_lru_locks mdc
10839         test_mkdir $DIR/$tdir
10840         createmany -o $DIR/$tdir/f $nr ||
10841                 error "failed to create $nr files in $DIR/$tdir"
10842         ls -l $DIR/$tdir > /dev/null
10843
10844         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10845         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10846         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10847         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10848         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10849
10850         # set lru_max_age to 1 sec
10851         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10852         echo "sleep $((recalc_p * 2)) seconds..."
10853         sleep $((recalc_p * 2))
10854
10855         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10856         # restore lru_max_age
10857         $LCTL set_param -n $nsdir.lru_max_age $max_age
10858         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10859         unlinkmany $DIR/$tdir/f $nr
10860 }
10861 run_test 124c "LRUR cancel very aged locks"
10862
10863 test_124d() {
10864         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10865         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10866                 skip_env "no lru resize on server"
10867
10868         # cache ununsed locks on client
10869         local nr=100
10870
10871         lru_resize_disable mdc
10872         stack_trap "lru_resize_enable mdc" EXIT
10873
10874         cancel_lru_locks mdc
10875
10876         # asynchronous object destroy at MDT could cause bl ast to client
10877         test_mkdir $DIR/$tdir
10878         createmany -o $DIR/$tdir/f $nr ||
10879                 error "failed to create $nr files in $DIR/$tdir"
10880         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
10881
10882         ls -l $DIR/$tdir > /dev/null
10883
10884         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
10885         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
10886         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
10887         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
10888
10889         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
10890
10891         # set lru_max_age to 1 sec
10892         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
10893         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
10894
10895         echo "sleep $((recalc_p * 2)) seconds..."
10896         sleep $((recalc_p * 2))
10897
10898         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
10899
10900         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
10901 }
10902 run_test 124d "cancel very aged locks if lru-resize diasbaled"
10903
10904 test_125() { # 13358
10905         $LCTL get_param -n llite.*.client_type | grep -q local ||
10906                 skip "must run as local client"
10907         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
10908                 skip_env "must have acl enabled"
10909         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
10910
10911         test_mkdir $DIR/$tdir
10912         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
10913         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
10914         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
10915 }
10916 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
10917
10918 test_126() { # bug 12829/13455
10919         $GSS && skip_env "must run as gss disabled"
10920         $LCTL get_param -n llite.*.client_type | grep -q local ||
10921                 skip "must run as local client"
10922         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
10923
10924         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
10925         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
10926         rm -f $DIR/$tfile
10927         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
10928 }
10929 run_test 126 "check that the fsgid provided by the client is taken into account"
10930
10931 test_127a() { # bug 15521
10932         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10933
10934         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
10935         $LCTL set_param osc.*.stats=0
10936         FSIZE=$((2048 * 1024))
10937         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
10938         cancel_lru_locks osc
10939         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
10940
10941         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
10942         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
10943                 echo "got $COUNT $NAME"
10944                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
10945                 eval $NAME=$COUNT || error "Wrong proc format"
10946
10947                 case $NAME in
10948                         read_bytes|write_bytes)
10949                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
10950                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
10951                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
10952                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
10953                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
10954                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
10955                                 error "sumsquare is too small: $SUMSQ"
10956                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
10957                                 error "sumsquare is too big: $SUMSQ"
10958                         ;;
10959                         *) ;;
10960                 esac
10961         done < $DIR/${tfile}.tmp
10962
10963         #check that we actually got some stats
10964         [ "$read_bytes" ] || error "Missing read_bytes stats"
10965         [ "$write_bytes" ] || error "Missing write_bytes stats"
10966         [ "$read_bytes" != 0 ] || error "no read done"
10967         [ "$write_bytes" != 0 ] || error "no write done"
10968 }
10969 run_test 127a "verify the client stats are sane"
10970
10971 test_127b() { # bug LU-333
10972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10973         local name count samp unit min max sum sumsq
10974
10975         $LCTL set_param llite.*.stats=0
10976
10977         # perform 2 reads and writes so MAX is different from SUM.
10978         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10979         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
10980         cancel_lru_locks osc
10981         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10982         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
10983
10984         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
10985         while read name count samp unit min max sum sumsq; do
10986                 echo "got $count $name"
10987                 eval $name=$count || error "Wrong proc format"
10988
10989                 case $name in
10990                 read_bytes)
10991                         [ $count -ne 2 ] && error "count is not 2: $count"
10992                         [ $min -ne $PAGE_SIZE ] &&
10993                                 error "min is not $PAGE_SIZE: $min"
10994                         [ $max -ne $PAGE_SIZE ] &&
10995                                 error "max is incorrect: $max"
10996                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
10997                                 error "sum is wrong: $sum"
10998                         ;;
10999                 write_bytes)
11000                         [ $count -ne 2 ] && error "count is not 2: $count"
11001                         [ $min -ne $PAGE_SIZE ] &&
11002                                 error "min is not $PAGE_SIZE: $min"
11003                         [ $max -ne $PAGE_SIZE ] &&
11004                                 error "max is incorrect: $max"
11005                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11006                                 error "sum is wrong: $sum"
11007                         ;;
11008                 *) ;;
11009                 esac
11010         done < $TMP/$tfile.tmp
11011
11012         #check that we actually got some stats
11013         [ "$read_bytes" ] || error "Missing read_bytes stats"
11014         [ "$write_bytes" ] || error "Missing write_bytes stats"
11015         [ "$read_bytes" != 0 ] || error "no read done"
11016         [ "$write_bytes" != 0 ] || error "no write done"
11017
11018         rm -f $TMP/${tfile}.tmp
11019 }
11020 run_test 127b "verify the llite client stats are sane"
11021
11022 test_127c() { # LU-12394
11023         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11024         local size
11025         local bsize
11026         local reads
11027         local writes
11028         local count
11029
11030         $LCTL set_param llite.*.extents_stats=1
11031         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11032
11033         # Use two stripes so there is enough space in default config
11034         $LFS setstripe -c 2 $DIR/$tfile
11035
11036         # Extent stats start at 0-4K and go in power of two buckets
11037         # LL_HIST_START = 12 --> 2^12 = 4K
11038         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11039         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11040         # small configs
11041         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11042                 do
11043                 # Write and read, 2x each, second time at a non-zero offset
11044                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11045                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11046                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11047                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11048                 rm -f $DIR/$tfile
11049         done
11050
11051         $LCTL get_param llite.*.extents_stats
11052
11053         count=2
11054         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11055                 do
11056                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11057                                 grep -m 1 $bsize)
11058                 reads=$(echo $bucket | awk '{print $5}')
11059                 writes=$(echo $bucket | awk '{print $9}')
11060                 [ "$reads" -eq $count ] ||
11061                         error "$reads reads in < $bsize bucket, expect $count"
11062                 [ "$writes" -eq $count ] ||
11063                         error "$writes writes in < $bsize bucket, expect $count"
11064         done
11065
11066         # Test mmap write and read
11067         $LCTL set_param llite.*.extents_stats=c
11068         size=512
11069         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11070         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11071         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11072
11073         $LCTL get_param llite.*.extents_stats
11074
11075         count=$(((size*1024) / PAGE_SIZE))
11076
11077         bsize=$((2 * PAGE_SIZE / 1024))K
11078
11079         bucket=$($LCTL get_param -n llite.*.extents_stats |
11080                         grep -m 1 $bsize)
11081         reads=$(echo $bucket | awk '{print $5}')
11082         writes=$(echo $bucket | awk '{print $9}')
11083         # mmap writes fault in the page first, creating an additonal read
11084         [ "$reads" -eq $((2 * count)) ] ||
11085                 error "$reads reads in < $bsize bucket, expect $count"
11086         [ "$writes" -eq $count ] ||
11087                 error "$writes writes in < $bsize bucket, expect $count"
11088 }
11089 run_test 127c "test llite extent stats with regular & mmap i/o"
11090
11091 test_128() { # bug 15212
11092         touch $DIR/$tfile
11093         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11094                 find $DIR/$tfile
11095                 find $DIR/$tfile
11096         EOF
11097
11098         result=$(grep error $TMP/$tfile.log)
11099         rm -f $DIR/$tfile $TMP/$tfile.log
11100         [ -z "$result" ] ||
11101                 error "consecutive find's under interactive lfs failed"
11102 }
11103 run_test 128 "interactive lfs for 2 consecutive find's"
11104
11105 set_dir_limits () {
11106         local mntdev
11107         local canondev
11108         local node
11109
11110         local ldproc=/proc/fs/ldiskfs
11111         local facets=$(get_facets MDS)
11112
11113         for facet in ${facets//,/ }; do
11114                 canondev=$(ldiskfs_canon \
11115                            *.$(convert_facet2label $facet).mntdev $facet)
11116                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11117                         ldproc=/sys/fs/ldiskfs
11118                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11119                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11120         done
11121 }
11122
11123 check_mds_dmesg() {
11124         local facets=$(get_facets MDS)
11125         for facet in ${facets//,/ }; do
11126                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11127         done
11128         return 1
11129 }
11130
11131 test_129() {
11132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11133         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11134                 skip "Need MDS version with at least 2.5.56"
11135         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11136                 skip_env "ldiskfs only test"
11137         fi
11138         remote_mds_nodsh && skip "remote MDS with nodsh"
11139
11140         local ENOSPC=28
11141         local EFBIG=27
11142         local has_warning=false
11143
11144         rm -rf $DIR/$tdir
11145         mkdir -p $DIR/$tdir
11146
11147         # block size of mds1
11148         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11149         set_dir_limits $maxsize $maxsize
11150         local dirsize=$(stat -c%s "$DIR/$tdir")
11151         local nfiles=0
11152         while [[ $dirsize -le $maxsize ]]; do
11153                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11154                 rc=$?
11155                 if ! $has_warning; then
11156                         check_mds_dmesg '"is approaching"' && has_warning=true
11157                 fi
11158                 # check two errors:
11159                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11160                 # EFBIG for previous versions included in ldiskfs series
11161                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11162                         set_dir_limits 0 0
11163                         echo "return code $rc received as expected"
11164
11165                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11166                                 error_exit "create failed w/o dir size limit"
11167
11168                         check_mds_dmesg '"has reached"' ||
11169                                 error_exit "reached message should be output"
11170
11171                         [ $has_warning = "false" ] &&
11172                                 error_exit "warning message should be output"
11173
11174                         dirsize=$(stat -c%s "$DIR/$tdir")
11175
11176                         [[ $dirsize -ge $maxsize ]] && return 0
11177                         error_exit "current dir size $dirsize, " \
11178                                    "previous limit $maxsize"
11179                 elif [ $rc -ne 0 ]; then
11180                         set_dir_limits 0 0
11181                         error_exit "return $rc received instead of expected " \
11182                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11183                 fi
11184                 nfiles=$((nfiles + 1))
11185                 dirsize=$(stat -c%s "$DIR/$tdir")
11186         done
11187
11188         set_dir_limits 0 0
11189         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11190 }
11191 run_test 129 "test directory size limit ========================"
11192
11193 OLDIFS="$IFS"
11194 cleanup_130() {
11195         trap 0
11196         IFS="$OLDIFS"
11197 }
11198
11199 test_130a() {
11200         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11201         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11202
11203         trap cleanup_130 EXIT RETURN
11204
11205         local fm_file=$DIR/$tfile
11206         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11207         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11208                 error "dd failed for $fm_file"
11209
11210         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11211         filefrag -ves $fm_file
11212         RC=$?
11213         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11214                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11215         [ $RC != 0 ] && error "filefrag $fm_file failed"
11216
11217         filefrag_op=$(filefrag -ve -k $fm_file |
11218                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11219         lun=$($LFS getstripe -i $fm_file)
11220
11221         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11222         IFS=$'\n'
11223         tot_len=0
11224         for line in $filefrag_op
11225         do
11226                 frag_lun=`echo $line | cut -d: -f5`
11227                 ext_len=`echo $line | cut -d: -f4`
11228                 if (( $frag_lun != $lun )); then
11229                         cleanup_130
11230                         error "FIEMAP on 1-stripe file($fm_file) failed"
11231                         return
11232                 fi
11233                 (( tot_len += ext_len ))
11234         done
11235
11236         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11237                 cleanup_130
11238                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11239                 return
11240         fi
11241
11242         cleanup_130
11243
11244         echo "FIEMAP on single striped file succeeded"
11245 }
11246 run_test 130a "FIEMAP (1-stripe file)"
11247
11248 test_130b() {
11249         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11250
11251         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11252         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11253
11254         trap cleanup_130 EXIT RETURN
11255
11256         local fm_file=$DIR/$tfile
11257         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11258                         error "setstripe on $fm_file"
11259         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11260                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11261
11262         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11263                 error "dd failed on $fm_file"
11264
11265         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11266         filefrag_op=$(filefrag -ve -k $fm_file |
11267                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11268
11269         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11270                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11271
11272         IFS=$'\n'
11273         tot_len=0
11274         num_luns=1
11275         for line in $filefrag_op
11276         do
11277                 frag_lun=$(echo $line | cut -d: -f5 |
11278                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11279                 ext_len=$(echo $line | cut -d: -f4)
11280                 if (( $frag_lun != $last_lun )); then
11281                         if (( tot_len != 1024 )); then
11282                                 cleanup_130
11283                                 error "FIEMAP on $fm_file failed; returned " \
11284                                 "len $tot_len for OST $last_lun instead of 1024"
11285                                 return
11286                         else
11287                                 (( num_luns += 1 ))
11288                                 tot_len=0
11289                         fi
11290                 fi
11291                 (( tot_len += ext_len ))
11292                 last_lun=$frag_lun
11293         done
11294         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11295                 cleanup_130
11296                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11297                         "luns or wrong len for OST $last_lun"
11298                 return
11299         fi
11300
11301         cleanup_130
11302
11303         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11304 }
11305 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11306
11307 test_130c() {
11308         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11309
11310         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11311         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11312
11313         trap cleanup_130 EXIT RETURN
11314
11315         local fm_file=$DIR/$tfile
11316         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11317         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11318                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11319
11320         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11321                         error "dd failed on $fm_file"
11322
11323         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11324         filefrag_op=$(filefrag -ve -k $fm_file |
11325                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11326
11327         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11328                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11329
11330         IFS=$'\n'
11331         tot_len=0
11332         num_luns=1
11333         for line in $filefrag_op
11334         do
11335                 frag_lun=$(echo $line | cut -d: -f5 |
11336                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11337                 ext_len=$(echo $line | cut -d: -f4)
11338                 if (( $frag_lun != $last_lun )); then
11339                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11340                         if (( logical != 512 )); then
11341                                 cleanup_130
11342                                 error "FIEMAP on $fm_file failed; returned " \
11343                                 "logical start for lun $logical instead of 512"
11344                                 return
11345                         fi
11346                         if (( tot_len != 512 )); then
11347                                 cleanup_130
11348                                 error "FIEMAP on $fm_file failed; returned " \
11349                                 "len $tot_len for OST $last_lun instead of 1024"
11350                                 return
11351                         else
11352                                 (( num_luns += 1 ))
11353                                 tot_len=0
11354                         fi
11355                 fi
11356                 (( tot_len += ext_len ))
11357                 last_lun=$frag_lun
11358         done
11359         if (( num_luns != 2 || tot_len != 512 )); then
11360                 cleanup_130
11361                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11362                         "luns or wrong len for OST $last_lun"
11363                 return
11364         fi
11365
11366         cleanup_130
11367
11368         echo "FIEMAP on 2-stripe file with hole succeeded"
11369 }
11370 run_test 130c "FIEMAP (2-stripe file with hole)"
11371
11372 test_130d() {
11373         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11374
11375         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11376         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11377
11378         trap cleanup_130 EXIT RETURN
11379
11380         local fm_file=$DIR/$tfile
11381         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11382                         error "setstripe on $fm_file"
11383         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11384                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11385
11386         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11387         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11388                 error "dd failed on $fm_file"
11389
11390         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11391         filefrag_op=$(filefrag -ve -k $fm_file |
11392                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11393
11394         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11395                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11396
11397         IFS=$'\n'
11398         tot_len=0
11399         num_luns=1
11400         for line in $filefrag_op
11401         do
11402                 frag_lun=$(echo $line | cut -d: -f5 |
11403                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11404                 ext_len=$(echo $line | cut -d: -f4)
11405                 if (( $frag_lun != $last_lun )); then
11406                         if (( tot_len != 1024 )); then
11407                                 cleanup_130
11408                                 error "FIEMAP on $fm_file failed; returned " \
11409                                 "len $tot_len for OST $last_lun instead of 1024"
11410                                 return
11411                         else
11412                                 (( num_luns += 1 ))
11413                                 tot_len=0
11414                         fi
11415                 fi
11416                 (( tot_len += ext_len ))
11417                 last_lun=$frag_lun
11418         done
11419         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11420                 cleanup_130
11421                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11422                         "luns or wrong len for OST $last_lun"
11423                 return
11424         fi
11425
11426         cleanup_130
11427
11428         echo "FIEMAP on N-stripe file succeeded"
11429 }
11430 run_test 130d "FIEMAP (N-stripe file)"
11431
11432 test_130e() {
11433         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11434
11435         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11436         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11437
11438         trap cleanup_130 EXIT RETURN
11439
11440         local fm_file=$DIR/$tfile
11441         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11442         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11443                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11444
11445         NUM_BLKS=512
11446         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11447         for ((i = 0; i < $NUM_BLKS; i++))
11448         do
11449                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11450         done
11451
11452         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11453         filefrag_op=$(filefrag -ve -k $fm_file |
11454                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11455
11456         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11457                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11458
11459         IFS=$'\n'
11460         tot_len=0
11461         num_luns=1
11462         for line in $filefrag_op
11463         do
11464                 frag_lun=$(echo $line | cut -d: -f5 |
11465                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11466                 ext_len=$(echo $line | cut -d: -f4)
11467                 if (( $frag_lun != $last_lun )); then
11468                         if (( tot_len != $EXPECTED_LEN )); then
11469                                 cleanup_130
11470                                 error "FIEMAP on $fm_file failed; returned " \
11471                                 "len $tot_len for OST $last_lun instead " \
11472                                 "of $EXPECTED_LEN"
11473                                 return
11474                         else
11475                                 (( num_luns += 1 ))
11476                                 tot_len=0
11477                         fi
11478                 fi
11479                 (( tot_len += ext_len ))
11480                 last_lun=$frag_lun
11481         done
11482         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11483                 cleanup_130
11484                 error "FIEMAP on $fm_file failed; returned wrong number " \
11485                         "of luns or wrong len for OST $last_lun"
11486                 return
11487         fi
11488
11489         cleanup_130
11490
11491         echo "FIEMAP with continuation calls succeeded"
11492 }
11493 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11494
11495 test_130f() {
11496         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11497         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11498
11499         local fm_file=$DIR/$tfile
11500         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11501                 error "multiop create with lov_delay_create on $fm_file"
11502
11503         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11504         filefrag_extents=$(filefrag -vek $fm_file |
11505                            awk '/extents? found/ { print $2 }')
11506         if [[ "$filefrag_extents" != "0" ]]; then
11507                 error "FIEMAP on $fm_file failed; " \
11508                       "returned $filefrag_extents expected 0"
11509         fi
11510
11511         rm -f $fm_file
11512 }
11513 run_test 130f "FIEMAP (unstriped file)"
11514
11515 # Test for writev/readv
11516 test_131a() {
11517         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11518                 error "writev test failed"
11519         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11520                 error "readv failed"
11521         rm -f $DIR/$tfile
11522 }
11523 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11524
11525 test_131b() {
11526         local fsize=$((524288 + 1048576 + 1572864))
11527         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11528                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11529                         error "append writev test failed"
11530
11531         ((fsize += 1572864 + 1048576))
11532         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11533                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11534                         error "append writev test failed"
11535         rm -f $DIR/$tfile
11536 }
11537 run_test 131b "test append writev"
11538
11539 test_131c() {
11540         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11541         error "NOT PASS"
11542 }
11543 run_test 131c "test read/write on file w/o objects"
11544
11545 test_131d() {
11546         rwv -f $DIR/$tfile -w -n 1 1572864
11547         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11548         if [ "$NOB" != 1572864 ]; then
11549                 error "Short read filed: read $NOB bytes instead of 1572864"
11550         fi
11551         rm -f $DIR/$tfile
11552 }
11553 run_test 131d "test short read"
11554
11555 test_131e() {
11556         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11557         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11558         error "read hitting hole failed"
11559         rm -f $DIR/$tfile
11560 }
11561 run_test 131e "test read hitting hole"
11562
11563 check_stats() {
11564         local facet=$1
11565         local op=$2
11566         local want=${3:-0}
11567         local res
11568
11569         case $facet in
11570         mds*) res=$(do_facet $facet \
11571                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11572                  ;;
11573         ost*) res=$(do_facet $facet \
11574                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11575                  ;;
11576         *) error "Wrong facet '$facet'" ;;
11577         esac
11578         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11579         # if the argument $3 is zero, it means any stat increment is ok.
11580         if [[ $want -gt 0 ]]; then
11581                 local count=$(echo $res | awk '{ print $2 }')
11582                 [[ $count -ne $want ]] &&
11583                         error "The $op counter on $facet is $count, not $want"
11584         fi
11585 }
11586
11587 test_133a() {
11588         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11589         remote_ost_nodsh && skip "remote OST with nodsh"
11590         remote_mds_nodsh && skip "remote MDS with nodsh"
11591         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11592                 skip_env "MDS doesn't support rename stats"
11593
11594         local testdir=$DIR/${tdir}/stats_testdir
11595
11596         mkdir -p $DIR/${tdir}
11597
11598         # clear stats.
11599         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11600         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11601
11602         # verify mdt stats first.
11603         mkdir ${testdir} || error "mkdir failed"
11604         check_stats $SINGLEMDS "mkdir" 1
11605         touch ${testdir}/${tfile} || error "touch failed"
11606         check_stats $SINGLEMDS "open" 1
11607         check_stats $SINGLEMDS "close" 1
11608         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11609                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11610                 check_stats $SINGLEMDS "mknod" 2
11611         }
11612         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11613         check_stats $SINGLEMDS "unlink" 1
11614         rm -f ${testdir}/${tfile} || error "file remove failed"
11615         check_stats $SINGLEMDS "unlink" 2
11616
11617         # remove working dir and check mdt stats again.
11618         rmdir ${testdir} || error "rmdir failed"
11619         check_stats $SINGLEMDS "rmdir" 1
11620
11621         local testdir1=$DIR/${tdir}/stats_testdir1
11622         mkdir -p ${testdir}
11623         mkdir -p ${testdir1}
11624         touch ${testdir1}/test1
11625         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11626         check_stats $SINGLEMDS "crossdir_rename" 1
11627
11628         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11629         check_stats $SINGLEMDS "samedir_rename" 1
11630
11631         rm -rf $DIR/${tdir}
11632 }
11633 run_test 133a "Verifying MDT stats ========================================"
11634
11635 test_133b() {
11636         local res
11637
11638         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11639         remote_ost_nodsh && skip "remote OST with nodsh"
11640         remote_mds_nodsh && skip "remote MDS with nodsh"
11641
11642         local testdir=$DIR/${tdir}/stats_testdir
11643
11644         mkdir -p ${testdir} || error "mkdir failed"
11645         touch ${testdir}/${tfile} || error "touch failed"
11646         cancel_lru_locks mdc
11647
11648         # clear stats.
11649         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11650         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11651
11652         # extra mdt stats verification.
11653         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11654         check_stats $SINGLEMDS "setattr" 1
11655         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11656         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11657         then            # LU-1740
11658                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11659                 check_stats $SINGLEMDS "getattr" 1
11660         fi
11661         rm -rf $DIR/${tdir}
11662
11663         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11664         # so the check below is not reliable
11665         [ $MDSCOUNT -eq 1 ] || return 0
11666
11667         # Sleep to avoid a cached response.
11668         #define OBD_STATFS_CACHE_SECONDS 1
11669         sleep 2
11670         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11671         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11672         $LFS df || error "lfs failed"
11673         check_stats $SINGLEMDS "statfs" 1
11674
11675         # check aggregated statfs (LU-10018)
11676         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11677                 return 0
11678         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11679                 return 0
11680         sleep 2
11681         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11682         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11683         df $DIR
11684         check_stats $SINGLEMDS "statfs" 1
11685
11686         # We want to check that the client didn't send OST_STATFS to
11687         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11688         # extra care is needed here.
11689         if remote_mds; then
11690                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11691                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11692
11693                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11694                 [ "$res" ] && error "OST got STATFS"
11695         fi
11696
11697         return 0
11698 }
11699 run_test 133b "Verifying extra MDT stats =================================="
11700
11701 test_133c() {
11702         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11703         remote_ost_nodsh && skip "remote OST with nodsh"
11704         remote_mds_nodsh && skip "remote MDS with nodsh"
11705
11706         local testdir=$DIR/$tdir/stats_testdir
11707
11708         test_mkdir -p $testdir
11709
11710         # verify obdfilter stats.
11711         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11712         sync
11713         cancel_lru_locks osc
11714         wait_delete_completed
11715
11716         # clear stats.
11717         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11718         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11719
11720         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11721                 error "dd failed"
11722         sync
11723         cancel_lru_locks osc
11724         check_stats ost1 "write" 1
11725
11726         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11727         check_stats ost1 "read" 1
11728
11729         > $testdir/$tfile || error "truncate failed"
11730         check_stats ost1 "punch" 1
11731
11732         rm -f $testdir/$tfile || error "file remove failed"
11733         wait_delete_completed
11734         check_stats ost1 "destroy" 1
11735
11736         rm -rf $DIR/$tdir
11737 }
11738 run_test 133c "Verifying OST stats ========================================"
11739
11740 order_2() {
11741         local value=$1
11742         local orig=$value
11743         local order=1
11744
11745         while [ $value -ge 2 ]; do
11746                 order=$((order*2))
11747                 value=$((value/2))
11748         done
11749
11750         if [ $orig -gt $order ]; then
11751                 order=$((order*2))
11752         fi
11753         echo $order
11754 }
11755
11756 size_in_KMGT() {
11757     local value=$1
11758     local size=('K' 'M' 'G' 'T');
11759     local i=0
11760     local size_string=$value
11761
11762     while [ $value -ge 1024 ]; do
11763         if [ $i -gt 3 ]; then
11764             #T is the biggest unit we get here, if that is bigger,
11765             #just return XXXT
11766             size_string=${value}T
11767             break
11768         fi
11769         value=$((value >> 10))
11770         if [ $value -lt 1024 ]; then
11771             size_string=${value}${size[$i]}
11772             break
11773         fi
11774         i=$((i + 1))
11775     done
11776
11777     echo $size_string
11778 }
11779
11780 get_rename_size() {
11781         local size=$1
11782         local context=${2:-.}
11783         local sample=$(do_facet $SINGLEMDS $LCTL \
11784                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11785                 grep -A1 $context |
11786                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11787         echo $sample
11788 }
11789
11790 test_133d() {
11791         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11792         remote_ost_nodsh && skip "remote OST with nodsh"
11793         remote_mds_nodsh && skip "remote MDS with nodsh"
11794         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11795                 skip_env "MDS doesn't support rename stats"
11796
11797         local testdir1=$DIR/${tdir}/stats_testdir1
11798         local testdir2=$DIR/${tdir}/stats_testdir2
11799         mkdir -p $DIR/${tdir}
11800
11801         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11802
11803         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
11804         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
11805
11806         createmany -o $testdir1/test 512 || error "createmany failed"
11807
11808         # check samedir rename size
11809         mv ${testdir1}/test0 ${testdir1}/test_0
11810
11811         local testdir1_size=$(ls -l $DIR/${tdir} |
11812                 awk '/stats_testdir1/ {print $5}')
11813         local testdir2_size=$(ls -l $DIR/${tdir} |
11814                 awk '/stats_testdir2/ {print $5}')
11815
11816         testdir1_size=$(order_2 $testdir1_size)
11817         testdir2_size=$(order_2 $testdir2_size)
11818
11819         testdir1_size=$(size_in_KMGT $testdir1_size)
11820         testdir2_size=$(size_in_KMGT $testdir2_size)
11821
11822         echo "source rename dir size: ${testdir1_size}"
11823         echo "target rename dir size: ${testdir2_size}"
11824
11825         local cmd="do_facet $SINGLEMDS $LCTL "
11826         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
11827
11828         eval $cmd || error "$cmd failed"
11829         local samedir=$($cmd | grep 'same_dir')
11830         local same_sample=$(get_rename_size $testdir1_size)
11831         [ -z "$samedir" ] && error "samedir_rename_size count error"
11832         [[ $same_sample -eq 1 ]] ||
11833                 error "samedir_rename_size error $same_sample"
11834         echo "Check same dir rename stats success"
11835
11836         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
11837
11838         # check crossdir rename size
11839         mv ${testdir1}/test_0 ${testdir2}/test_0
11840
11841         testdir1_size=$(ls -l $DIR/${tdir} |
11842                 awk '/stats_testdir1/ {print $5}')
11843         testdir2_size=$(ls -l $DIR/${tdir} |
11844                 awk '/stats_testdir2/ {print $5}')
11845
11846         testdir1_size=$(order_2 $testdir1_size)
11847         testdir2_size=$(order_2 $testdir2_size)
11848
11849         testdir1_size=$(size_in_KMGT $testdir1_size)
11850         testdir2_size=$(size_in_KMGT $testdir2_size)
11851
11852         echo "source rename dir size: ${testdir1_size}"
11853         echo "target rename dir size: ${testdir2_size}"
11854
11855         eval $cmd || error "$cmd failed"
11856         local crossdir=$($cmd | grep 'crossdir')
11857         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
11858         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
11859         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
11860         [[ $src_sample -eq 1 ]] ||
11861                 error "crossdir_rename_size error $src_sample"
11862         [[ $tgt_sample -eq 1 ]] ||
11863                 error "crossdir_rename_size error $tgt_sample"
11864         echo "Check cross dir rename stats success"
11865         rm -rf $DIR/${tdir}
11866 }
11867 run_test 133d "Verifying rename_stats ========================================"
11868
11869 test_133e() {
11870         remote_mds_nodsh && skip "remote MDS with nodsh"
11871         remote_ost_nodsh && skip "remote OST with nodsh"
11872         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11873
11874         local testdir=$DIR/${tdir}/stats_testdir
11875         local ctr f0 f1 bs=32768 count=42 sum
11876
11877         mkdir -p ${testdir} || error "mkdir failed"
11878
11879         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
11880
11881         for ctr in {write,read}_bytes; do
11882                 sync
11883                 cancel_lru_locks osc
11884
11885                 do_facet ost1 $LCTL set_param -n \
11886                         "obdfilter.*.exports.clear=clear"
11887
11888                 if [ $ctr = write_bytes ]; then
11889                         f0=/dev/zero
11890                         f1=${testdir}/${tfile}
11891                 else
11892                         f0=${testdir}/${tfile}
11893                         f1=/dev/null
11894                 fi
11895
11896                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
11897                         error "dd failed"
11898                 sync
11899                 cancel_lru_locks osc
11900
11901                 sum=$(do_facet ost1 $LCTL get_param \
11902                         "obdfilter.*.exports.*.stats" |
11903                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
11904                                 $1 == ctr { sum += $7 }
11905                                 END { printf("%0.0f", sum) }')
11906
11907                 if ((sum != bs * count)); then
11908                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
11909                 fi
11910         done
11911
11912         rm -rf $DIR/${tdir}
11913 }
11914 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
11915
11916 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
11917
11918 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
11919 # not honor the -ignore_readdir_race option correctly. So we call
11920 # error_ignore() rather than error() in these cases. See LU-11152.
11921 error_133() {
11922         if (find --version; do_facet mds1 find --version) |
11923                 grep -q '\b4\.5\.1[1-4]\b'; then
11924                 error_ignore LU-11152 "$@"
11925         else
11926                 error "$@"
11927         fi
11928 }
11929
11930 test_133f() {
11931         # First without trusting modes.
11932         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
11933         echo "proc_dirs='$proc_dirs'"
11934         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
11935         find $proc_dirs -exec cat '{}' \; &> /dev/null
11936
11937         # Second verifying readability.
11938         $LCTL get_param -R '*' &> /dev/null
11939
11940         # Verifing writability with badarea_io.
11941         find $proc_dirs \
11942                 -ignore_readdir_race \
11943                 -type f \
11944                 -not -name force_lbug \
11945                 -not -name changelog_mask \
11946                 -exec badarea_io '{}' \; ||
11947                         error_133 "find $proc_dirs failed"
11948 }
11949 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
11950
11951 test_133g() {
11952         remote_mds_nodsh && skip "remote MDS with nodsh"
11953         remote_ost_nodsh && skip "remote OST with nodsh"
11954
11955         # eventually, this can also be replaced with "lctl get_param -R",
11956         # but not until that option is always available on the server
11957         local facet
11958         for facet in mds1 ost1; do
11959                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
11960                         skip_noexit "Too old lustre on $facet"
11961                 local facet_proc_dirs=$(do_facet $facet \
11962                                         \\\ls -d $proc_regexp 2>/dev/null)
11963                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
11964                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
11965                 do_facet $facet find $facet_proc_dirs \
11966                         ! -name req_history \
11967                         -exec cat '{}' \\\; &> /dev/null
11968
11969                 do_facet $facet find $facet_proc_dirs \
11970                         ! -name req_history \
11971                         -type f \
11972                         -exec cat '{}' \\\; &> /dev/null ||
11973                                 error "proc file read failed"
11974
11975                 do_facet $facet find $facet_proc_dirs \
11976                         -ignore_readdir_race \
11977                         -type f \
11978                         -not -name force_lbug \
11979                         -not -name changelog_mask \
11980                         -exec badarea_io '{}' \\\; ||
11981                                 error_133 "$facet find $facet_proc_dirs failed"
11982         done
11983
11984         # remount the FS in case writes/reads /proc break the FS
11985         cleanup || error "failed to unmount"
11986         setup || error "failed to setup"
11987         true
11988 }
11989 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
11990
11991 test_133h() {
11992         remote_mds_nodsh && skip "remote MDS with nodsh"
11993         remote_ost_nodsh && skip "remote OST with nodsh"
11994         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
11995                 skip "Need MDS version at least 2.9.54"
11996
11997         local facet
11998
11999         for facet in client mds1 ost1; do
12000                 local facet_proc_dirs=$(do_facet $facet \
12001                                         \\\ls -d $proc_regexp 2> /dev/null)
12002                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12003                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12004                 # Get the list of files that are missing the terminating newline
12005                 local missing=($(do_facet $facet \
12006                         find ${facet_proc_dirs} -type f \|              \
12007                                 while read F\; do                       \
12008                                         awk -v FS='\v' -v RS='\v\v'     \
12009                                         "'END { if(NR>0 &&              \
12010                                         \\\$NF !~ /.*\\\n\$/)           \
12011                                                 print FILENAME}'"       \
12012                                         '\$F'\;                         \
12013                                 done 2>/dev/null))
12014                 [ ${#missing[*]} -eq 0 ] ||
12015                         error "files do not end with newline: ${missing[*]}"
12016         done
12017 }
12018 run_test 133h "Proc files should end with newlines"
12019
12020 test_134a() {
12021         remote_mds_nodsh && skip "remote MDS with nodsh"
12022         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12023                 skip "Need MDS version at least 2.7.54"
12024
12025         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12026         cancel_lru_locks mdc
12027
12028         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12029         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12030         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12031
12032         local nr=1000
12033         createmany -o $DIR/$tdir/f $nr ||
12034                 error "failed to create $nr files in $DIR/$tdir"
12035         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12036
12037         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12038         do_facet mds1 $LCTL set_param fail_loc=0x327
12039         do_facet mds1 $LCTL set_param fail_val=500
12040         touch $DIR/$tdir/m
12041
12042         echo "sleep 10 seconds ..."
12043         sleep 10
12044         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12045
12046         do_facet mds1 $LCTL set_param fail_loc=0
12047         do_facet mds1 $LCTL set_param fail_val=0
12048         [ $lck_cnt -lt $unused ] ||
12049                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12050
12051         rm $DIR/$tdir/m
12052         unlinkmany $DIR/$tdir/f $nr
12053 }
12054 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12055
12056 test_134b() {
12057         remote_mds_nodsh && skip "remote MDS with nodsh"
12058         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12059                 skip "Need MDS version at least 2.7.54"
12060
12061         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12062         cancel_lru_locks mdc
12063
12064         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12065                         ldlm.lock_reclaim_threshold_mb)
12066         # disable reclaim temporarily
12067         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12068
12069         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12070         do_facet mds1 $LCTL set_param fail_loc=0x328
12071         do_facet mds1 $LCTL set_param fail_val=500
12072
12073         $LCTL set_param debug=+trace
12074
12075         local nr=600
12076         createmany -o $DIR/$tdir/f $nr &
12077         local create_pid=$!
12078
12079         echo "Sleep $TIMEOUT seconds ..."
12080         sleep $TIMEOUT
12081         if ! ps -p $create_pid  > /dev/null 2>&1; then
12082                 do_facet mds1 $LCTL set_param fail_loc=0
12083                 do_facet mds1 $LCTL set_param fail_val=0
12084                 do_facet mds1 $LCTL set_param \
12085                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12086                 error "createmany finished incorrectly!"
12087         fi
12088         do_facet mds1 $LCTL set_param fail_loc=0
12089         do_facet mds1 $LCTL set_param fail_val=0
12090         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12091         wait $create_pid || return 1
12092
12093         unlinkmany $DIR/$tdir/f $nr
12094 }
12095 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12096
12097 test_140() { #bug-17379
12098         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12099
12100         test_mkdir $DIR/$tdir
12101         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12102         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12103
12104         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12105         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12106         local i=0
12107         while i=$((i + 1)); do
12108                 test_mkdir $i
12109                 cd $i || error "Changing to $i"
12110                 ln -s ../stat stat || error "Creating stat symlink"
12111                 # Read the symlink until ELOOP present,
12112                 # not LBUGing the system is considered success,
12113                 # we didn't overrun the stack.
12114                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12115                 if [ $ret -ne 0 ]; then
12116                         if [ $ret -eq 40 ]; then
12117                                 break  # -ELOOP
12118                         else
12119                                 error "Open stat symlink"
12120                                         return
12121                         fi
12122                 fi
12123         done
12124         i=$((i - 1))
12125         echo "The symlink depth = $i"
12126         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12127                 error "Invalid symlink depth"
12128
12129         # Test recursive symlink
12130         ln -s symlink_self symlink_self
12131         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12132         echo "open symlink_self returns $ret"
12133         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12134 }
12135 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12136
12137 test_150() {
12138         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12139
12140         local TF="$TMP/$tfile"
12141
12142         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12143         cp $TF $DIR/$tfile
12144         cancel_lru_locks $OSC
12145         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12146         remount_client $MOUNT
12147         df -P $MOUNT
12148         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12149
12150         $TRUNCATE $TF 6000
12151         $TRUNCATE $DIR/$tfile 6000
12152         cancel_lru_locks $OSC
12153         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12154
12155         echo "12345" >>$TF
12156         echo "12345" >>$DIR/$tfile
12157         cancel_lru_locks $OSC
12158         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12159
12160         echo "12345" >>$TF
12161         echo "12345" >>$DIR/$tfile
12162         cancel_lru_locks $OSC
12163         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12164
12165         rm -f $TF
12166         true
12167 }
12168 run_test 150 "truncate/append tests"
12169
12170 #LU-2902 roc_hit was not able to read all values from lproc
12171 function roc_hit_init() {
12172         local list=$(comma_list $(osts_nodes))
12173         local dir=$DIR/$tdir-check
12174         local file=$dir/$tfile
12175         local BEFORE
12176         local AFTER
12177         local idx
12178
12179         test_mkdir $dir
12180         #use setstripe to do a write to every ost
12181         for i in $(seq 0 $((OSTCOUNT-1))); do
12182                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12183                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12184                 idx=$(printf %04x $i)
12185                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12186                         awk '$1 == "cache_access" {sum += $7}
12187                                 END { printf("%0.0f", sum) }')
12188
12189                 cancel_lru_locks osc
12190                 cat $file >/dev/null
12191
12192                 AFTER=$(get_osd_param $list *OST*$idx stats |
12193                         awk '$1 == "cache_access" {sum += $7}
12194                                 END { printf("%0.0f", sum) }')
12195
12196                 echo BEFORE:$BEFORE AFTER:$AFTER
12197                 if ! let "AFTER - BEFORE == 4"; then
12198                         rm -rf $dir
12199                         error "roc_hit is not safe to use"
12200                 fi
12201                 rm $file
12202         done
12203
12204         rm -rf $dir
12205 }
12206
12207 function roc_hit() {
12208         local list=$(comma_list $(osts_nodes))
12209         echo $(get_osd_param $list '' stats |
12210                 awk '$1 == "cache_hit" {sum += $7}
12211                         END { printf("%0.0f", sum) }')
12212 }
12213
12214 function set_cache() {
12215         local on=1
12216
12217         if [ "$2" == "off" ]; then
12218                 on=0;
12219         fi
12220         local list=$(comma_list $(osts_nodes))
12221         set_osd_param $list '' $1_cache_enable $on
12222
12223         cancel_lru_locks osc
12224 }
12225
12226 test_151() {
12227         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12228         remote_ost_nodsh && skip "remote OST with nodsh"
12229
12230         local CPAGES=3
12231         local list=$(comma_list $(osts_nodes))
12232
12233         # check whether obdfilter is cache capable at all
12234         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12235                 skip "not cache-capable obdfilter"
12236         fi
12237
12238         # check cache is enabled on all obdfilters
12239         if get_osd_param $list '' read_cache_enable | grep 0; then
12240                 skip "oss cache is disabled"
12241         fi
12242
12243         set_osd_param $list '' writethrough_cache_enable 1
12244
12245         # check write cache is enabled on all obdfilters
12246         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12247                 skip "oss write cache is NOT enabled"
12248         fi
12249
12250         roc_hit_init
12251
12252         #define OBD_FAIL_OBD_NO_LRU  0x609
12253         do_nodes $list $LCTL set_param fail_loc=0x609
12254
12255         # pages should be in the case right after write
12256         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12257                 error "dd failed"
12258
12259         local BEFORE=$(roc_hit)
12260         cancel_lru_locks osc
12261         cat $DIR/$tfile >/dev/null
12262         local AFTER=$(roc_hit)
12263
12264         do_nodes $list $LCTL set_param fail_loc=0
12265
12266         if ! let "AFTER - BEFORE == CPAGES"; then
12267                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12268         fi
12269
12270         # the following read invalidates the cache
12271         cancel_lru_locks osc
12272         set_osd_param $list '' read_cache_enable 0
12273         cat $DIR/$tfile >/dev/null
12274
12275         # now data shouldn't be found in the cache
12276         BEFORE=$(roc_hit)
12277         cancel_lru_locks osc
12278         cat $DIR/$tfile >/dev/null
12279         AFTER=$(roc_hit)
12280         if let "AFTER - BEFORE != 0"; then
12281                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12282         fi
12283
12284         set_osd_param $list '' read_cache_enable 1
12285         rm -f $DIR/$tfile
12286 }
12287 run_test 151 "test cache on oss and controls ==============================="
12288
12289 test_152() {
12290         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12291
12292         local TF="$TMP/$tfile"
12293
12294         # simulate ENOMEM during write
12295 #define OBD_FAIL_OST_NOMEM      0x226
12296         lctl set_param fail_loc=0x80000226
12297         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12298         cp $TF $DIR/$tfile
12299         sync || error "sync failed"
12300         lctl set_param fail_loc=0
12301
12302         # discard client's cache
12303         cancel_lru_locks osc
12304
12305         # simulate ENOMEM during read
12306         lctl set_param fail_loc=0x80000226
12307         cmp $TF $DIR/$tfile || error "cmp failed"
12308         lctl set_param fail_loc=0
12309
12310         rm -f $TF
12311 }
12312 run_test 152 "test read/write with enomem ============================"
12313
12314 test_153() {
12315         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12316 }
12317 run_test 153 "test if fdatasync does not crash ======================="
12318
12319 dot_lustre_fid_permission_check() {
12320         local fid=$1
12321         local ffid=$MOUNT/.lustre/fid/$fid
12322         local test_dir=$2
12323
12324         echo "stat fid $fid"
12325         stat $ffid > /dev/null || error "stat $ffid failed."
12326         echo "touch fid $fid"
12327         touch $ffid || error "touch $ffid failed."
12328         echo "write to fid $fid"
12329         cat /etc/hosts > $ffid || error "write $ffid failed."
12330         echo "read fid $fid"
12331         diff /etc/hosts $ffid || error "read $ffid failed."
12332         echo "append write to fid $fid"
12333         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12334         echo "rename fid $fid"
12335         mv $ffid $test_dir/$tfile.1 &&
12336                 error "rename $ffid to $tfile.1 should fail."
12337         touch $test_dir/$tfile.1
12338         mv $test_dir/$tfile.1 $ffid &&
12339                 error "rename $tfile.1 to $ffid should fail."
12340         rm -f $test_dir/$tfile.1
12341         echo "truncate fid $fid"
12342         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12343         echo "link fid $fid"
12344         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12345         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12346                 echo "setfacl fid $fid"
12347                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12348                 echo "getfacl fid $fid"
12349                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12350         fi
12351         echo "unlink fid $fid"
12352         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12353         echo "mknod fid $fid"
12354         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12355
12356         fid=[0xf00000400:0x1:0x0]
12357         ffid=$MOUNT/.lustre/fid/$fid
12358
12359         echo "stat non-exist fid $fid"
12360         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12361         echo "write to non-exist fid $fid"
12362         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12363         echo "link new fid $fid"
12364         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12365
12366         mkdir -p $test_dir/$tdir
12367         touch $test_dir/$tdir/$tfile
12368         fid=$($LFS path2fid $test_dir/$tdir)
12369         rc=$?
12370         [ $rc -ne 0 ] &&
12371                 error "error: could not get fid for $test_dir/$dir/$tfile."
12372
12373         ffid=$MOUNT/.lustre/fid/$fid
12374
12375         echo "ls $fid"
12376         ls $ffid > /dev/null || error "ls $ffid failed."
12377         echo "touch $fid/$tfile.1"
12378         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12379
12380         echo "touch $MOUNT/.lustre/fid/$tfile"
12381         touch $MOUNT/.lustre/fid/$tfile && \
12382                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12383
12384         echo "setxattr to $MOUNT/.lustre/fid"
12385         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12386
12387         echo "listxattr for $MOUNT/.lustre/fid"
12388         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12389
12390         echo "delxattr from $MOUNT/.lustre/fid"
12391         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12392
12393         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12394         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12395                 error "touch invalid fid should fail."
12396
12397         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12398         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12399                 error "touch non-normal fid should fail."
12400
12401         echo "rename $tdir to $MOUNT/.lustre/fid"
12402         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12403                 error "rename to $MOUNT/.lustre/fid should fail."
12404
12405         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12406         then            # LU-3547
12407                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12408                 local new_obf_mode=777
12409
12410                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12411                 chmod $new_obf_mode $DIR/.lustre/fid ||
12412                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12413
12414                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12415                 [ $obf_mode -eq $new_obf_mode ] ||
12416                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12417
12418                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12419                 chmod $old_obf_mode $DIR/.lustre/fid ||
12420                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12421         fi
12422
12423         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12424         fid=$($LFS path2fid $test_dir/$tfile-2)
12425
12426         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12427         then # LU-5424
12428                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12429                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12430                         error "create lov data thru .lustre failed"
12431         fi
12432         echo "cp /etc/passwd $test_dir/$tfile-2"
12433         cp /etc/passwd $test_dir/$tfile-2 ||
12434                 error "copy to $test_dir/$tfile-2 failed."
12435         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12436         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12437                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12438
12439         rm -rf $test_dir/tfile.lnk
12440         rm -rf $test_dir/$tfile-2
12441 }
12442
12443 test_154A() {
12444         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12445                 skip "Need MDS version at least 2.4.1"
12446
12447         local tf=$DIR/$tfile
12448         touch $tf
12449
12450         local fid=$($LFS path2fid $tf)
12451         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12452
12453         # check that we get the same pathname back
12454         local found=$($LFS fid2path $MOUNT "$fid")
12455         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12456         [ "$found" == "$tf" ] ||
12457                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12458 }
12459 run_test 154A "lfs path2fid and fid2path basic checks"
12460
12461 test_154B() {
12462         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12463                 skip "Need MDS version at least 2.4.1"
12464
12465         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12466         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12467         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12468         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12469
12470         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12471         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12472
12473         # check that we get the same pathname
12474         echo "PFID: $PFID, name: $name"
12475         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12476         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12477         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12478                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12479
12480         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12481 }
12482 run_test 154B "verify the ll_decode_linkea tool"
12483
12484 test_154a() {
12485         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12486         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12487         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12488                 skip "Need MDS version at least 2.2.51"
12489         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12490
12491         cp /etc/hosts $DIR/$tfile
12492
12493         fid=$($LFS path2fid $DIR/$tfile)
12494         rc=$?
12495         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12496
12497         dot_lustre_fid_permission_check "$fid" $DIR ||
12498                 error "dot lustre permission check $fid failed"
12499
12500         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12501
12502         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12503
12504         touch $MOUNT/.lustre/file &&
12505                 error "creation is not allowed under .lustre"
12506
12507         mkdir $MOUNT/.lustre/dir &&
12508                 error "mkdir is not allowed under .lustre"
12509
12510         rm -rf $DIR/$tfile
12511 }
12512 run_test 154a "Open-by-FID"
12513
12514 test_154b() {
12515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12516         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12517         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12518         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12519                 skip "Need MDS version at least 2.2.51"
12520
12521         local remote_dir=$DIR/$tdir/remote_dir
12522         local MDTIDX=1
12523         local rc=0
12524
12525         mkdir -p $DIR/$tdir
12526         $LFS mkdir -i $MDTIDX $remote_dir ||
12527                 error "create remote directory failed"
12528
12529         cp /etc/hosts $remote_dir/$tfile
12530
12531         fid=$($LFS path2fid $remote_dir/$tfile)
12532         rc=$?
12533         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12534
12535         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12536                 error "dot lustre permission check $fid failed"
12537         rm -rf $DIR/$tdir
12538 }
12539 run_test 154b "Open-by-FID for remote directory"
12540
12541 test_154c() {
12542         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12543                 skip "Need MDS version at least 2.4.1"
12544
12545         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12546         local FID1=$($LFS path2fid $DIR/$tfile.1)
12547         local FID2=$($LFS path2fid $DIR/$tfile.2)
12548         local FID3=$($LFS path2fid $DIR/$tfile.3)
12549
12550         local N=1
12551         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12552                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12553                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12554                 local want=FID$N
12555                 [ "$FID" = "${!want}" ] ||
12556                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12557                 N=$((N + 1))
12558         done
12559
12560         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12561         do
12562                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12563                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12564                 N=$((N + 1))
12565         done
12566 }
12567 run_test 154c "lfs path2fid and fid2path multiple arguments"
12568
12569 test_154d() {
12570         remote_mds_nodsh && skip "remote MDS with nodsh"
12571         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12572                 skip "Need MDS version at least 2.5.53"
12573
12574         if remote_mds; then
12575                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12576         else
12577                 nid="0@lo"
12578         fi
12579         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12580         local fd
12581         local cmd
12582
12583         rm -f $DIR/$tfile
12584         touch $DIR/$tfile
12585
12586         local fid=$($LFS path2fid $DIR/$tfile)
12587         # Open the file
12588         fd=$(free_fd)
12589         cmd="exec $fd<$DIR/$tfile"
12590         eval $cmd
12591         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12592         echo "$fid_list" | grep "$fid"
12593         rc=$?
12594
12595         cmd="exec $fd>/dev/null"
12596         eval $cmd
12597         if [ $rc -ne 0 ]; then
12598                 error "FID $fid not found in open files list $fid_list"
12599         fi
12600 }
12601 run_test 154d "Verify open file fid"
12602
12603 test_154e()
12604 {
12605         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12606                 skip "Need MDS version at least 2.6.50"
12607
12608         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12609                 error ".lustre returned by readdir"
12610         fi
12611 }
12612 run_test 154e ".lustre is not returned by readdir"
12613
12614 test_154f() {
12615         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12616
12617         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12618         test_mkdir -p -c1 $DIR/$tdir/d
12619         # test dirs inherit from its stripe
12620         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12621         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12622         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12623         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12624         touch $DIR/f
12625
12626         # get fid of parents
12627         local FID0=$($LFS path2fid $DIR/$tdir/d)
12628         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12629         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12630         local FID3=$($LFS path2fid $DIR)
12631
12632         # check that path2fid --parents returns expected <parent_fid>/name
12633         # 1) test for a directory (single parent)
12634         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12635         [ "$parent" == "$FID0/foo1" ] ||
12636                 error "expected parent: $FID0/foo1, got: $parent"
12637
12638         # 2) test for a file with nlink > 1 (multiple parents)
12639         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12640         echo "$parent" | grep -F "$FID1/$tfile" ||
12641                 error "$FID1/$tfile not returned in parent list"
12642         echo "$parent" | grep -F "$FID2/link" ||
12643                 error "$FID2/link not returned in parent list"
12644
12645         # 3) get parent by fid
12646         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12647         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12648         echo "$parent" | grep -F "$FID1/$tfile" ||
12649                 error "$FID1/$tfile not returned in parent list (by fid)"
12650         echo "$parent" | grep -F "$FID2/link" ||
12651                 error "$FID2/link not returned in parent list (by fid)"
12652
12653         # 4) test for entry in root directory
12654         parent=$($LFS path2fid --parents $DIR/f)
12655         echo "$parent" | grep -F "$FID3/f" ||
12656                 error "$FID3/f not returned in parent list"
12657
12658         # 5) test it on root directory
12659         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12660                 error "$MOUNT should not have parents"
12661
12662         # enable xattr caching and check that linkea is correctly updated
12663         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12664         save_lustre_params client "llite.*.xattr_cache" > $save
12665         lctl set_param llite.*.xattr_cache 1
12666
12667         # 6.1) linkea update on rename
12668         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12669
12670         # get parents by fid
12671         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12672         # foo1 should no longer be returned in parent list
12673         echo "$parent" | grep -F "$FID1" &&
12674                 error "$FID1 should no longer be in parent list"
12675         # the new path should appear
12676         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12677                 error "$FID2/$tfile.moved is not in parent list"
12678
12679         # 6.2) linkea update on unlink
12680         rm -f $DIR/$tdir/d/foo2/link
12681         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12682         # foo2/link should no longer be returned in parent list
12683         echo "$parent" | grep -F "$FID2/link" &&
12684                 error "$FID2/link should no longer be in parent list"
12685         true
12686
12687         rm -f $DIR/f
12688         restore_lustre_params < $save
12689         rm -f $save
12690 }
12691 run_test 154f "get parent fids by reading link ea"
12692
12693 test_154g()
12694 {
12695         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12696         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12697            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12698                 skip "Need MDS version at least 2.6.92"
12699
12700         mkdir -p $DIR/$tdir
12701         llapi_fid_test -d $DIR/$tdir
12702 }
12703 run_test 154g "various llapi FID tests"
12704
12705 test_155_small_load() {
12706     local temp=$TMP/$tfile
12707     local file=$DIR/$tfile
12708
12709     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12710         error "dd of=$temp bs=6096 count=1 failed"
12711     cp $temp $file
12712     cancel_lru_locks $OSC
12713     cmp $temp $file || error "$temp $file differ"
12714
12715     $TRUNCATE $temp 6000
12716     $TRUNCATE $file 6000
12717     cmp $temp $file || error "$temp $file differ (truncate1)"
12718
12719     echo "12345" >>$temp
12720     echo "12345" >>$file
12721     cmp $temp $file || error "$temp $file differ (append1)"
12722
12723     echo "12345" >>$temp
12724     echo "12345" >>$file
12725     cmp $temp $file || error "$temp $file differ (append2)"
12726
12727     rm -f $temp $file
12728     true
12729 }
12730
12731 test_155_big_load() {
12732         remote_ost_nodsh && skip "remote OST with nodsh"
12733
12734         local temp=$TMP/$tfile
12735         local file=$DIR/$tfile
12736
12737         free_min_max
12738         local cache_size=$(do_facet ost$((MAXI+1)) \
12739                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12740         local large_file_size=$((cache_size * 2))
12741
12742         echo "OSS cache size: $cache_size KB"
12743         echo "Large file size: $large_file_size KB"
12744
12745         [ $MAXV -le $large_file_size ] &&
12746                 skip_env "max available OST size needs > $large_file_size KB"
12747
12748         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12749
12750         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12751                 error "dd of=$temp bs=$large_file_size count=1k failed"
12752         cp $temp $file
12753         ls -lh $temp $file
12754         cancel_lru_locks osc
12755         cmp $temp $file || error "$temp $file differ"
12756
12757         rm -f $temp $file
12758         true
12759 }
12760
12761 save_writethrough() {
12762         local facets=$(get_facets OST)
12763
12764         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12765 }
12766
12767 test_155a() {
12768         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12769
12770         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12771
12772         save_writethrough $p
12773
12774         set_cache read on
12775         set_cache writethrough on
12776         test_155_small_load
12777         restore_lustre_params < $p
12778         rm -f $p
12779 }
12780 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12781
12782 test_155b() {
12783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12784
12785         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12786
12787         save_writethrough $p
12788
12789         set_cache read on
12790         set_cache writethrough off
12791         test_155_small_load
12792         restore_lustre_params < $p
12793         rm -f $p
12794 }
12795 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
12796
12797 test_155c() {
12798         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12799
12800         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12801
12802         save_writethrough $p
12803
12804         set_cache read off
12805         set_cache writethrough on
12806         test_155_small_load
12807         restore_lustre_params < $p
12808         rm -f $p
12809 }
12810 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
12811
12812 test_155d() {
12813         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12814
12815         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12816
12817         save_writethrough $p
12818
12819         set_cache read off
12820         set_cache writethrough off
12821         test_155_small_load
12822         restore_lustre_params < $p
12823         rm -f $p
12824 }
12825 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
12826
12827 test_155e() {
12828         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12829
12830         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12831
12832         save_writethrough $p
12833
12834         set_cache read on
12835         set_cache writethrough on
12836         test_155_big_load
12837         restore_lustre_params < $p
12838         rm -f $p
12839 }
12840 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
12841
12842 test_155f() {
12843         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12844
12845         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12846
12847         save_writethrough $p
12848
12849         set_cache read on
12850         set_cache writethrough off
12851         test_155_big_load
12852         restore_lustre_params < $p
12853         rm -f $p
12854 }
12855 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
12856
12857 test_155g() {
12858         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12859
12860         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12861
12862         save_writethrough $p
12863
12864         set_cache read off
12865         set_cache writethrough on
12866         test_155_big_load
12867         restore_lustre_params < $p
12868         rm -f $p
12869 }
12870 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
12871
12872 test_155h() {
12873         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12874
12875         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12876
12877         save_writethrough $p
12878
12879         set_cache read off
12880         set_cache writethrough off
12881         test_155_big_load
12882         restore_lustre_params < $p
12883         rm -f $p
12884 }
12885 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
12886
12887 test_156() {
12888         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12889         remote_ost_nodsh && skip "remote OST with nodsh"
12890         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
12891                 skip "stats not implemented on old servers"
12892         [ "$ost1_FSTYPE" = "zfs" ] &&
12893                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
12894
12895         local CPAGES=3
12896         local BEFORE
12897         local AFTER
12898         local file="$DIR/$tfile"
12899         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12900
12901         save_writethrough $p
12902         roc_hit_init
12903
12904         log "Turn on read and write cache"
12905         set_cache read on
12906         set_cache writethrough on
12907
12908         log "Write data and read it back."
12909         log "Read should be satisfied from the cache."
12910         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12911         BEFORE=$(roc_hit)
12912         cancel_lru_locks osc
12913         cat $file >/dev/null
12914         AFTER=$(roc_hit)
12915         if ! let "AFTER - BEFORE == CPAGES"; then
12916                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12917         else
12918                 log "cache hits:: before: $BEFORE, after: $AFTER"
12919         fi
12920
12921         log "Read again; it should be satisfied from the cache."
12922         BEFORE=$AFTER
12923         cancel_lru_locks osc
12924         cat $file >/dev/null
12925         AFTER=$(roc_hit)
12926         if ! let "AFTER - BEFORE == CPAGES"; then
12927                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12928         else
12929                 log "cache hits:: before: $BEFORE, after: $AFTER"
12930         fi
12931
12932         log "Turn off the read cache and turn on the write cache"
12933         set_cache read off
12934         set_cache writethrough on
12935
12936         log "Read again; it should be satisfied from the cache."
12937         BEFORE=$(roc_hit)
12938         cancel_lru_locks osc
12939         cat $file >/dev/null
12940         AFTER=$(roc_hit)
12941         if ! let "AFTER - BEFORE == CPAGES"; then
12942                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12943         else
12944                 log "cache hits:: before: $BEFORE, after: $AFTER"
12945         fi
12946
12947         log "Read again; it should not be satisfied from the cache."
12948         BEFORE=$AFTER
12949         cancel_lru_locks osc
12950         cat $file >/dev/null
12951         AFTER=$(roc_hit)
12952         if ! let "AFTER - BEFORE == 0"; then
12953                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12954         else
12955                 log "cache hits:: before: $BEFORE, after: $AFTER"
12956         fi
12957
12958         log "Write data and read it back."
12959         log "Read should be satisfied from the cache."
12960         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12961         BEFORE=$(roc_hit)
12962         cancel_lru_locks osc
12963         cat $file >/dev/null
12964         AFTER=$(roc_hit)
12965         if ! let "AFTER - BEFORE == CPAGES"; then
12966                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12967         else
12968                 log "cache hits:: before: $BEFORE, after: $AFTER"
12969         fi
12970
12971         log "Read again; it should not be satisfied from the cache."
12972         BEFORE=$AFTER
12973         cancel_lru_locks osc
12974         cat $file >/dev/null
12975         AFTER=$(roc_hit)
12976         if ! let "AFTER - BEFORE == 0"; then
12977                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12978         else
12979                 log "cache hits:: before: $BEFORE, after: $AFTER"
12980         fi
12981
12982         log "Turn off read and write cache"
12983         set_cache read off
12984         set_cache writethrough off
12985
12986         log "Write data and read it back"
12987         log "It should not be satisfied from the cache."
12988         rm -f $file
12989         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
12990         cancel_lru_locks osc
12991         BEFORE=$(roc_hit)
12992         cat $file >/dev/null
12993         AFTER=$(roc_hit)
12994         if ! let "AFTER - BEFORE == 0"; then
12995                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
12996         else
12997                 log "cache hits:: before: $BEFORE, after: $AFTER"
12998         fi
12999
13000         log "Turn on the read cache and turn off the write cache"
13001         set_cache read on
13002         set_cache writethrough off
13003
13004         log "Write data and read it back"
13005         log "It should not be satisfied from the cache."
13006         rm -f $file
13007         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13008         BEFORE=$(roc_hit)
13009         cancel_lru_locks osc
13010         cat $file >/dev/null
13011         AFTER=$(roc_hit)
13012         if ! let "AFTER - BEFORE == 0"; then
13013                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13014         else
13015                 log "cache hits:: before: $BEFORE, after: $AFTER"
13016         fi
13017
13018         log "Read again; it should be satisfied from the cache."
13019         BEFORE=$(roc_hit)
13020         cancel_lru_locks osc
13021         cat $file >/dev/null
13022         AFTER=$(roc_hit)
13023         if ! let "AFTER - BEFORE == CPAGES"; then
13024                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13025         else
13026                 log "cache hits:: before: $BEFORE, after: $AFTER"
13027         fi
13028
13029         restore_lustre_params < $p
13030         rm -f $p $file
13031 }
13032 run_test 156 "Verification of tunables"
13033
13034 test_160a() {
13035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13036         remote_mds_nodsh && skip "remote MDS with nodsh"
13037         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13038                 skip "Need MDS version at least 2.2.0"
13039
13040         changelog_register || error "changelog_register failed"
13041         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13042         changelog_users $SINGLEMDS | grep -q $cl_user ||
13043                 error "User $cl_user not found in changelog_users"
13044
13045         # change something
13046         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13047         changelog_clear 0 || error "changelog_clear failed"
13048         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13049         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13050         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13051         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13052         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13053         rm $DIR/$tdir/pics/desktop.jpg
13054
13055         changelog_dump | tail -10
13056
13057         echo "verifying changelog mask"
13058         changelog_chmask "-MKDIR"
13059         changelog_chmask "-CLOSE"
13060
13061         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13062         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13063
13064         changelog_chmask "+MKDIR"
13065         changelog_chmask "+CLOSE"
13066
13067         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13068         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13069
13070         changelog_dump | tail -10
13071         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13072         CLOSES=$(changelog_dump | grep -c "CLOSE")
13073         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13074         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13075
13076         # verify contents
13077         echo "verifying target fid"
13078         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13079         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13080         [ "$fidc" == "$fidf" ] ||
13081                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13082         echo "verifying parent fid"
13083         # The FID returned from the Changelog may be the directory shard on
13084         # a different MDT, and not the FID returned by path2fid on the parent.
13085         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13086         # since this is what will matter when recreating this file in the tree.
13087         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13088         local pathp=$($LFS fid2path $MOUNT "$fidp")
13089         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13090                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13091
13092         echo "getting records for $cl_user"
13093         changelog_users $SINGLEMDS
13094         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13095         local nclr=3
13096         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13097                 error "changelog_clear failed"
13098         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13099         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13100         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13101                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13102
13103         local min0_rec=$(changelog_users $SINGLEMDS |
13104                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13105         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13106                           awk '{ print $1; exit; }')
13107
13108         changelog_dump | tail -n 5
13109         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13110         [ $first_rec == $((min0_rec + 1)) ] ||
13111                 error "first index should be $min0_rec + 1 not $first_rec"
13112
13113         # LU-3446 changelog index reset on MDT restart
13114         local cur_rec1=$(changelog_users $SINGLEMDS |
13115                          awk '/^current.index:/ { print $NF }')
13116         changelog_clear 0 ||
13117                 error "clear all changelog records for $cl_user failed"
13118         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13119         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13120                 error "Fail to start $SINGLEMDS"
13121         local cur_rec2=$(changelog_users $SINGLEMDS |
13122                          awk '/^current.index:/ { print $NF }')
13123         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13124         [ $cur_rec1 == $cur_rec2 ] ||
13125                 error "current index should be $cur_rec1 not $cur_rec2"
13126
13127         echo "verifying users from this test are deregistered"
13128         changelog_deregister || error "changelog_deregister failed"
13129         changelog_users $SINGLEMDS | grep -q $cl_user &&
13130                 error "User '$cl_user' still in changelog_users"
13131
13132         # lctl get_param -n mdd.*.changelog_users
13133         # current index: 144
13134         # ID    index (idle seconds)
13135         # cl3   144 (2)
13136         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13137                 # this is the normal case where all users were deregistered
13138                 # make sure no new records are added when no users are present
13139                 local last_rec1=$(changelog_users $SINGLEMDS |
13140                                   awk '/^current.index:/ { print $NF }')
13141                 touch $DIR/$tdir/chloe
13142                 local last_rec2=$(changelog_users $SINGLEMDS |
13143                                   awk '/^current.index:/ { print $NF }')
13144                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13145                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13146         else
13147                 # any changelog users must be leftovers from a previous test
13148                 changelog_users $SINGLEMDS
13149                 echo "other changelog users; can't verify off"
13150         fi
13151 }
13152 run_test 160a "changelog sanity"
13153
13154 test_160b() { # LU-3587
13155         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13156         remote_mds_nodsh && skip "remote MDS with nodsh"
13157         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13158                 skip "Need MDS version at least 2.2.0"
13159
13160         changelog_register || error "changelog_register failed"
13161         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13162         changelog_users $SINGLEMDS | grep -q $cl_user ||
13163                 error "User '$cl_user' not found in changelog_users"
13164
13165         local longname1=$(str_repeat a 255)
13166         local longname2=$(str_repeat b 255)
13167
13168         cd $DIR
13169         echo "creating very long named file"
13170         touch $longname1 || error "create of '$longname1' failed"
13171         echo "renaming very long named file"
13172         mv $longname1 $longname2
13173
13174         changelog_dump | grep RENME | tail -n 5
13175         rm -f $longname2
13176 }
13177 run_test 160b "Verify that very long rename doesn't crash in changelog"
13178
13179 test_160c() {
13180         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13181         remote_mds_nodsh && skip "remote MDS with nodsh"
13182
13183         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13184                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13185                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13186                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13187
13188         local rc=0
13189
13190         # Registration step
13191         changelog_register || error "changelog_register failed"
13192
13193         rm -rf $DIR/$tdir
13194         mkdir -p $DIR/$tdir
13195         $MCREATE $DIR/$tdir/foo_160c
13196         changelog_chmask "-TRUNC"
13197         $TRUNCATE $DIR/$tdir/foo_160c 200
13198         changelog_chmask "+TRUNC"
13199         $TRUNCATE $DIR/$tdir/foo_160c 199
13200         changelog_dump | tail -n 5
13201         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13202         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13203 }
13204 run_test 160c "verify that changelog log catch the truncate event"
13205
13206 test_160d() {
13207         remote_mds_nodsh && skip "remote MDS with nodsh"
13208         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13210         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13211                 skip "Need MDS version at least 2.7.60"
13212
13213         # Registration step
13214         changelog_register || error "changelog_register failed"
13215
13216         mkdir -p $DIR/$tdir/migrate_dir
13217         changelog_clear 0 || error "changelog_clear failed"
13218
13219         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13220         changelog_dump | tail -n 5
13221         local migrates=$(changelog_dump | grep -c "MIGRT")
13222         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13223 }
13224 run_test 160d "verify that changelog log catch the migrate event"
13225
13226 test_160e() {
13227         remote_mds_nodsh && skip "remote MDS with nodsh"
13228
13229         # Create a user
13230         changelog_register || error "changelog_register failed"
13231
13232         # Delete a future user (expect fail)
13233         local MDT0=$(facet_svc $SINGLEMDS)
13234         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13235         local rc=$?
13236
13237         if [ $rc -eq 0 ]; then
13238                 error "Deleted non-existant user cl77"
13239         elif [ $rc -ne 2 ]; then
13240                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13241         fi
13242
13243         # Clear to a bad index (1 billion should be safe)
13244         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13245         rc=$?
13246
13247         if [ $rc -eq 0 ]; then
13248                 error "Successfully cleared to invalid CL index"
13249         elif [ $rc -ne 22 ]; then
13250                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13251         fi
13252 }
13253 run_test 160e "changelog negative testing (should return errors)"
13254
13255 test_160f() {
13256         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13257         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13258                 skip "Need MDS version at least 2.10.56"
13259
13260         local mdts=$(comma_list $(mdts_nodes))
13261
13262         # Create a user
13263         changelog_register || error "first changelog_register failed"
13264         changelog_register || error "second changelog_register failed"
13265         local cl_users
13266         declare -A cl_user1
13267         declare -A cl_user2
13268         local user_rec1
13269         local user_rec2
13270         local i
13271
13272         # generate some changelog records to accumulate on each MDT
13273         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13274         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13275                 error "create $DIR/$tdir/$tfile failed"
13276
13277         # check changelogs have been generated
13278         local nbcl=$(changelog_dump | wc -l)
13279         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13280
13281         for param in "changelog_max_idle_time=10" \
13282                      "changelog_gc=1" \
13283                      "changelog_min_gc_interval=2" \
13284                      "changelog_min_free_cat_entries=3"; do
13285                 local MDT0=$(facet_svc $SINGLEMDS)
13286                 local var="${param%=*}"
13287                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13288
13289                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13290                 do_nodes $mdts $LCTL set_param mdd.*.$param
13291         done
13292
13293         # force cl_user2 to be idle (1st part)
13294         sleep 9
13295
13296         # simulate changelog catalog almost full
13297         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13298         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13299
13300         for i in $(seq $MDSCOUNT); do
13301                 cl_users=(${CL_USERS[mds$i]})
13302                 cl_user1[mds$i]="${cl_users[0]}"
13303                 cl_user2[mds$i]="${cl_users[1]}"
13304
13305                 [ -n "${cl_user1[mds$i]}" ] ||
13306                         error "mds$i: no user registered"
13307                 [ -n "${cl_user2[mds$i]}" ] ||
13308                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13309
13310                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13311                 [ -n "$user_rec1" ] ||
13312                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13313                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13314                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13315                 [ -n "$user_rec2" ] ||
13316                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13317                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13318                      "$user_rec1 + 2 == $user_rec2"
13319                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13320                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13321                               "$user_rec1 + 2, but is $user_rec2"
13322                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13323                 [ -n "$user_rec2" ] ||
13324                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13325                 [ $user_rec1 == $user_rec2 ] ||
13326                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13327                               "$user_rec1, but is $user_rec2"
13328         done
13329
13330         # force cl_user2 to be idle (2nd part) and to reach
13331         # changelog_max_idle_time
13332         sleep 2
13333
13334         # generate one more changelog to trigger fail_loc
13335         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13336                 error "create $DIR/$tdir/${tfile}bis failed"
13337
13338         # ensure gc thread is done
13339         for i in $(mdts_nodes); do
13340                 wait_update $i \
13341                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13342                         error "$i: GC-thread not done"
13343         done
13344
13345         local first_rec
13346         for i in $(seq $MDSCOUNT); do
13347                 # check cl_user1 still registered
13348                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13349                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13350                 # check cl_user2 unregistered
13351                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13352                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13353
13354                 # check changelogs are present and starting at $user_rec1 + 1
13355                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13356                 [ -n "$user_rec1" ] ||
13357                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13358                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13359                             awk '{ print $1; exit; }')
13360
13361                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13362                 [ $((user_rec1 + 1)) == $first_rec ] ||
13363                         error "mds$i: first index should be $user_rec1 + 1, " \
13364                               "but is $first_rec"
13365         done
13366 }
13367 run_test 160f "changelog garbage collect (timestamped users)"
13368
13369 test_160g() {
13370         remote_mds_nodsh && skip "remote MDS with nodsh"
13371         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13372                 skip "Need MDS version at least 2.10.56"
13373
13374         local mdts=$(comma_list $(mdts_nodes))
13375
13376         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13377         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13378
13379         # Create a user
13380         changelog_register || error "first changelog_register failed"
13381         changelog_register || error "second changelog_register failed"
13382         local cl_users
13383         declare -A cl_user1
13384         declare -A cl_user2
13385         local user_rec1
13386         local user_rec2
13387         local i
13388
13389         # generate some changelog records to accumulate on each MDT
13390         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13391         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13392                 error "create $DIR/$tdir/$tfile failed"
13393
13394         # check changelogs have been generated
13395         local nbcl=$(changelog_dump | wc -l)
13396         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13397
13398         # reduce the max_idle_indexes value to make sure we exceed it
13399         max_ndx=$((nbcl / 2 - 1))
13400
13401         for param in "changelog_max_idle_indexes=$max_ndx" \
13402                      "changelog_gc=1" \
13403                      "changelog_min_gc_interval=2" \
13404                      "changelog_min_free_cat_entries=3"; do
13405                 local MDT0=$(facet_svc $SINGLEMDS)
13406                 local var="${param%=*}"
13407                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13408
13409                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13410                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13411                         error "unable to set mdd.*.$param"
13412         done
13413
13414         # simulate changelog catalog almost full
13415         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13416         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13417
13418         for i in $(seq $MDSCOUNT); do
13419                 cl_users=(${CL_USERS[mds$i]})
13420                 cl_user1[mds$i]="${cl_users[0]}"
13421                 cl_user2[mds$i]="${cl_users[1]}"
13422
13423                 [ -n "${cl_user1[mds$i]}" ] ||
13424                         error "mds$i: no user registered"
13425                 [ -n "${cl_user2[mds$i]}" ] ||
13426                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13427
13428                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13429                 [ -n "$user_rec1" ] ||
13430                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13431                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13432                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13433                 [ -n "$user_rec2" ] ||
13434                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13435                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13436                      "$user_rec1 + 2 == $user_rec2"
13437                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13438                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13439                               "$user_rec1 + 2, but is $user_rec2"
13440                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13441                 [ -n "$user_rec2" ] ||
13442                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13443                 [ $user_rec1 == $user_rec2 ] ||
13444                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13445                               "$user_rec1, but is $user_rec2"
13446         done
13447
13448         # ensure we are past the previous changelog_min_gc_interval set above
13449         sleep 2
13450
13451         # generate one more changelog to trigger fail_loc
13452         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13453                 error "create $DIR/$tdir/${tfile}bis failed"
13454
13455         # ensure gc thread is done
13456         for i in $(mdts_nodes); do
13457                 wait_update $i \
13458                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13459                         error "$i: GC-thread not done"
13460         done
13461
13462         local first_rec
13463         for i in $(seq $MDSCOUNT); do
13464                 # check cl_user1 still registered
13465                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13466                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13467                 # check cl_user2 unregistered
13468                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13469                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13470
13471                 # check changelogs are present and starting at $user_rec1 + 1
13472                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13473                 [ -n "$user_rec1" ] ||
13474                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13475                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13476                             awk '{ print $1; exit; }')
13477
13478                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13479                 [ $((user_rec1 + 1)) == $first_rec ] ||
13480                         error "mds$i: first index should be $user_rec1 + 1, " \
13481                               "but is $first_rec"
13482         done
13483 }
13484 run_test 160g "changelog garbage collect (old users)"
13485
13486 test_160h() {
13487         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13488         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13489                 skip "Need MDS version at least 2.10.56"
13490
13491         local mdts=$(comma_list $(mdts_nodes))
13492
13493         # Create a user
13494         changelog_register || error "first changelog_register failed"
13495         changelog_register || error "second changelog_register failed"
13496         local cl_users
13497         declare -A cl_user1
13498         declare -A cl_user2
13499         local user_rec1
13500         local user_rec2
13501         local i
13502
13503         # generate some changelog records to accumulate on each MDT
13504         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13505         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13506                 error "create $DIR/$tdir/$tfile failed"
13507
13508         # check changelogs have been generated
13509         local nbcl=$(changelog_dump | wc -l)
13510         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13511
13512         for param in "changelog_max_idle_time=10" \
13513                      "changelog_gc=1" \
13514                      "changelog_min_gc_interval=2"; do
13515                 local MDT0=$(facet_svc $SINGLEMDS)
13516                 local var="${param%=*}"
13517                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13518
13519                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13520                 do_nodes $mdts $LCTL set_param mdd.*.$param
13521         done
13522
13523         # force cl_user2 to be idle (1st part)
13524         sleep 9
13525
13526         for i in $(seq $MDSCOUNT); do
13527                 cl_users=(${CL_USERS[mds$i]})
13528                 cl_user1[mds$i]="${cl_users[0]}"
13529                 cl_user2[mds$i]="${cl_users[1]}"
13530
13531                 [ -n "${cl_user1[mds$i]}" ] ||
13532                         error "mds$i: no user registered"
13533                 [ -n "${cl_user2[mds$i]}" ] ||
13534                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13535
13536                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13537                 [ -n "$user_rec1" ] ||
13538                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13539                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13540                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13541                 [ -n "$user_rec2" ] ||
13542                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13543                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13544                      "$user_rec1 + 2 == $user_rec2"
13545                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13546                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13547                               "$user_rec1 + 2, but is $user_rec2"
13548                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13549                 [ -n "$user_rec2" ] ||
13550                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13551                 [ $user_rec1 == $user_rec2 ] ||
13552                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13553                               "$user_rec1, but is $user_rec2"
13554         done
13555
13556         # force cl_user2 to be idle (2nd part) and to reach
13557         # changelog_max_idle_time
13558         sleep 2
13559
13560         # force each GC-thread start and block then
13561         # one per MDT/MDD, set fail_val accordingly
13562         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13563         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13564
13565         # generate more changelogs to trigger fail_loc
13566         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13567                 error "create $DIR/$tdir/${tfile}bis failed"
13568
13569         # stop MDT to stop GC-thread, should be done in back-ground as it will
13570         # block waiting for the thread to be released and exit
13571         declare -A stop_pids
13572         for i in $(seq $MDSCOUNT); do
13573                 stop mds$i &
13574                 stop_pids[mds$i]=$!
13575         done
13576
13577         for i in $(mdts_nodes); do
13578                 local facet
13579                 local nb=0
13580                 local facets=$(facets_up_on_host $i)
13581
13582                 for facet in ${facets//,/ }; do
13583                         if [[ $facet == mds* ]]; then
13584                                 nb=$((nb + 1))
13585                         fi
13586                 done
13587                 # ensure each MDS's gc threads are still present and all in "R"
13588                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13589                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13590                         error "$i: expected $nb GC-thread"
13591                 wait_update $i \
13592                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13593                         "R" 20 ||
13594                         error "$i: GC-thread not found in R-state"
13595                 # check umounts of each MDT on MDS have reached kthread_stop()
13596                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13597                         error "$i: expected $nb umount"
13598                 wait_update $i \
13599                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13600                         error "$i: umount not found in D-state"
13601         done
13602
13603         # release all GC-threads
13604         do_nodes $mdts $LCTL set_param fail_loc=0
13605
13606         # wait for MDT stop to complete
13607         for i in $(seq $MDSCOUNT); do
13608                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13609         done
13610
13611         # XXX
13612         # may try to check if any orphan changelog records are present
13613         # via ldiskfs/zfs and llog_reader...
13614
13615         # re-start/mount MDTs
13616         for i in $(seq $MDSCOUNT); do
13617                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13618                         error "Fail to start mds$i"
13619         done
13620
13621         local first_rec
13622         for i in $(seq $MDSCOUNT); do
13623                 # check cl_user1 still registered
13624                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13625                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13626                 # check cl_user2 unregistered
13627                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13628                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13629
13630                 # check changelogs are present and starting at $user_rec1 + 1
13631                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13632                 [ -n "$user_rec1" ] ||
13633                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13634                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13635                             awk '{ print $1; exit; }')
13636
13637                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13638                 [ $((user_rec1 + 1)) == $first_rec ] ||
13639                         error "mds$i: first index should be $user_rec1 + 1, " \
13640                               "but is $first_rec"
13641         done
13642 }
13643 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13644               "during mount"
13645
13646 test_160i() {
13647
13648         local mdts=$(comma_list $(mdts_nodes))
13649
13650         changelog_register || error "first changelog_register failed"
13651
13652         # generate some changelog records to accumulate on each MDT
13653         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13654         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13655                 error "create $DIR/$tdir/$tfile failed"
13656
13657         # check changelogs have been generated
13658         local nbcl=$(changelog_dump | wc -l)
13659         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13660
13661         # simulate race between register and unregister
13662         # XXX as fail_loc is set per-MDS, with DNE configs the race
13663         # simulation will only occur for one MDT per MDS and for the
13664         # others the normal race scenario will take place
13665         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13666         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13667         do_nodes $mdts $LCTL set_param fail_val=1
13668
13669         # unregister 1st user
13670         changelog_deregister &
13671         local pid1=$!
13672         # wait some time for deregister work to reach race rdv
13673         sleep 2
13674         # register 2nd user
13675         changelog_register || error "2nd user register failed"
13676
13677         wait $pid1 || error "1st user deregister failed"
13678
13679         local i
13680         local last_rec
13681         declare -A LAST_REC
13682         for i in $(seq $MDSCOUNT); do
13683                 if changelog_users mds$i | grep "^cl"; then
13684                         # make sure new records are added with one user present
13685                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13686                                           awk '/^current.index:/ { print $NF }')
13687                 else
13688                         error "mds$i has no user registered"
13689                 fi
13690         done
13691
13692         # generate more changelog records to accumulate on each MDT
13693         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13694                 error "create $DIR/$tdir/${tfile}bis failed"
13695
13696         for i in $(seq $MDSCOUNT); do
13697                 last_rec=$(changelog_users $SINGLEMDS |
13698                            awk '/^current.index:/ { print $NF }')
13699                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13700                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13701                         error "changelogs are off on mds$i"
13702         done
13703 }
13704 run_test 160i "changelog user register/unregister race"
13705
13706 test_161a() {
13707         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13708
13709         test_mkdir -c1 $DIR/$tdir
13710         cp /etc/hosts $DIR/$tdir/$tfile
13711         test_mkdir -c1 $DIR/$tdir/foo1
13712         test_mkdir -c1 $DIR/$tdir/foo2
13713         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13714         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13715         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13716         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13717         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13718         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13719                 $LFS fid2path $DIR $FID
13720                 error "bad link ea"
13721         fi
13722         # middle
13723         rm $DIR/$tdir/foo2/zachary
13724         # last
13725         rm $DIR/$tdir/foo2/thor
13726         # first
13727         rm $DIR/$tdir/$tfile
13728         # rename
13729         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13730         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13731                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13732         rm $DIR/$tdir/foo2/maggie
13733
13734         # overflow the EA
13735         local longname=$tfile.avg_len_is_thirty_two_
13736         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13737                 error_noexit 'failed to unlink many hardlinks'" EXIT
13738         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13739                 error "failed to hardlink many files"
13740         links=$($LFS fid2path $DIR $FID | wc -l)
13741         echo -n "${links}/1000 links in link EA"
13742         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13743 }
13744 run_test 161a "link ea sanity"
13745
13746 test_161b() {
13747         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13748         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13749
13750         local MDTIDX=1
13751         local remote_dir=$DIR/$tdir/remote_dir
13752
13753         mkdir -p $DIR/$tdir
13754         $LFS mkdir -i $MDTIDX $remote_dir ||
13755                 error "create remote directory failed"
13756
13757         cp /etc/hosts $remote_dir/$tfile
13758         mkdir -p $remote_dir/foo1
13759         mkdir -p $remote_dir/foo2
13760         ln $remote_dir/$tfile $remote_dir/foo1/sofia
13761         ln $remote_dir/$tfile $remote_dir/foo2/zachary
13762         ln $remote_dir/$tfile $remote_dir/foo1/luna
13763         ln $remote_dir/$tfile $remote_dir/foo2/thor
13764
13765         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
13766                      tr -d ']')
13767         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13768                 $LFS fid2path $DIR $FID
13769                 error "bad link ea"
13770         fi
13771         # middle
13772         rm $remote_dir/foo2/zachary
13773         # last
13774         rm $remote_dir/foo2/thor
13775         # first
13776         rm $remote_dir/$tfile
13777         # rename
13778         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
13779         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
13780         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
13781                 $LFS fid2path $DIR $FID
13782                 error "bad link rename"
13783         fi
13784         rm $remote_dir/foo2/maggie
13785
13786         # overflow the EA
13787         local longname=filename_avg_len_is_thirty_two_
13788         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
13789                 error "failed to hardlink many files"
13790         links=$($LFS fid2path $DIR $FID | wc -l)
13791         echo -n "${links}/1000 links in link EA"
13792         [[ ${links} -gt 60 ]] ||
13793                 error "expected at least 60 links in link EA"
13794         unlinkmany $remote_dir/foo2/$longname 1000 ||
13795         error "failed to unlink many hardlinks"
13796 }
13797 run_test 161b "link ea sanity under remote directory"
13798
13799 test_161c() {
13800         remote_mds_nodsh && skip "remote MDS with nodsh"
13801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13802         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
13803                 skip "Need MDS version at least 2.1.5"
13804
13805         # define CLF_RENAME_LAST 0x0001
13806         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
13807         changelog_register || error "changelog_register failed"
13808
13809         rm -rf $DIR/$tdir
13810         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
13811         touch $DIR/$tdir/foo_161c
13812         touch $DIR/$tdir/bar_161c
13813         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13814         changelog_dump | grep RENME | tail -n 5
13815         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13816         changelog_clear 0 || error "changelog_clear failed"
13817         if [ x$flags != "x0x1" ]; then
13818                 error "flag $flags is not 0x1"
13819         fi
13820
13821         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
13822         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
13823         touch $DIR/$tdir/foo_161c
13824         touch $DIR/$tdir/bar_161c
13825         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13826         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
13827         changelog_dump | grep RENME | tail -n 5
13828         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
13829         changelog_clear 0 || error "changelog_clear failed"
13830         if [ x$flags != "x0x0" ]; then
13831                 error "flag $flags is not 0x0"
13832         fi
13833         echo "rename overwrite a target having nlink > 1," \
13834                 "changelog record has flags of $flags"
13835
13836         # rename doesn't overwrite a target (changelog flag 0x0)
13837         touch $DIR/$tdir/foo_161c
13838         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
13839         changelog_dump | grep RENME | tail -n 5
13840         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
13841         changelog_clear 0 || error "changelog_clear failed"
13842         if [ x$flags != "x0x0" ]; then
13843                 error "flag $flags is not 0x0"
13844         fi
13845         echo "rename doesn't overwrite a target," \
13846                 "changelog record has flags of $flags"
13847
13848         # define CLF_UNLINK_LAST 0x0001
13849         # unlink a file having nlink = 1 (changelog flag 0x1)
13850         rm -f $DIR/$tdir/foo2_161c
13851         changelog_dump | grep UNLNK | tail -n 5
13852         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13853         changelog_clear 0 || error "changelog_clear failed"
13854         if [ x$flags != "x0x1" ]; then
13855                 error "flag $flags is not 0x1"
13856         fi
13857         echo "unlink a file having nlink = 1," \
13858                 "changelog record has flags of $flags"
13859
13860         # unlink a file having nlink > 1 (changelog flag 0x0)
13861         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
13862         rm -f $DIR/$tdir/foobar_161c
13863         changelog_dump | grep UNLNK | tail -n 5
13864         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
13865         changelog_clear 0 || error "changelog_clear failed"
13866         if [ x$flags != "x0x0" ]; then
13867                 error "flag $flags is not 0x0"
13868         fi
13869         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
13870 }
13871 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
13872
13873 test_161d() {
13874         remote_mds_nodsh && skip "remote MDS with nodsh"
13875         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
13876
13877         local pid
13878         local fid
13879
13880         changelog_register || error "changelog_register failed"
13881
13882         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
13883         # interfer with $MOUNT/.lustre/fid/ access
13884         mkdir $DIR/$tdir
13885         [[ $? -eq 0 ]] || error "mkdir failed"
13886
13887         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
13888         $LCTL set_param fail_loc=0x8000140c
13889         # 5s pause
13890         $LCTL set_param fail_val=5
13891
13892         # create file
13893         echo foofoo > $DIR/$tdir/$tfile &
13894         pid=$!
13895
13896         # wait for create to be delayed
13897         sleep 2
13898
13899         ps -p $pid
13900         [[ $? -eq 0 ]] || error "create should be blocked"
13901
13902         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
13903         stack_trap "rm -f $tempfile"
13904         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
13905         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
13906         # some delay may occur during ChangeLog publishing and file read just
13907         # above, that could allow file write to happen finally
13908         [[ -s $tempfile ]] && echo "file should be empty"
13909
13910         $LCTL set_param fail_loc=0
13911
13912         wait $pid
13913         [[ $? -eq 0 ]] || error "create failed"
13914 }
13915 run_test 161d "create with concurrent .lustre/fid access"
13916
13917 check_path() {
13918         local expected="$1"
13919         shift
13920         local fid="$2"
13921
13922         local path
13923         path=$($LFS fid2path "$@")
13924         local rc=$?
13925
13926         if [ $rc -ne 0 ]; then
13927                 error "path looked up of '$expected' failed: rc=$rc"
13928         elif [ "$path" != "$expected" ]; then
13929                 error "path looked up '$path' instead of '$expected'"
13930         else
13931                 echo "FID '$fid' resolves to path '$path' as expected"
13932         fi
13933 }
13934
13935 test_162a() { # was test_162
13936         test_mkdir -p -c1 $DIR/$tdir/d2
13937         touch $DIR/$tdir/d2/$tfile
13938         touch $DIR/$tdir/d2/x1
13939         touch $DIR/$tdir/d2/x2
13940         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
13941         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
13942         # regular file
13943         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
13944         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
13945
13946         # softlink
13947         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
13948         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
13949         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
13950
13951         # softlink to wrong file
13952         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
13953         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
13954         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
13955
13956         # hardlink
13957         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
13958         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
13959         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
13960         # fid2path dir/fsname should both work
13961         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
13962         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
13963
13964         # hardlink count: check that there are 2 links
13965         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
13966         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
13967
13968         # hardlink indexing: remove the first link
13969         rm $DIR/$tdir/d2/p/q/r/hlink
13970         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
13971 }
13972 run_test 162a "path lookup sanity"
13973
13974 test_162b() {
13975         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13976         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13977
13978         mkdir $DIR/$tdir
13979         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
13980                                 error "create striped dir failed"
13981
13982         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
13983                                         tail -n 1 | awk '{print $2}')
13984         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
13985
13986         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
13987         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
13988
13989         # regular file
13990         for ((i=0;i<5;i++)); do
13991                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
13992                         error "get fid for f$i failed"
13993                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
13994
13995                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
13996                         error "get fid for d$i failed"
13997                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
13998         done
13999
14000         return 0
14001 }
14002 run_test 162b "striped directory path lookup sanity"
14003
14004 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14005 test_162c() {
14006         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14007                 skip "Need MDS version at least 2.7.51"
14008
14009         local lpath=$tdir.local
14010         local rpath=$tdir.remote
14011
14012         test_mkdir $DIR/$lpath
14013         test_mkdir $DIR/$rpath
14014
14015         for ((i = 0; i <= 101; i++)); do
14016                 lpath="$lpath/$i"
14017                 mkdir $DIR/$lpath
14018                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14019                         error "get fid for local directory $DIR/$lpath failed"
14020                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14021
14022                 rpath="$rpath/$i"
14023                 test_mkdir $DIR/$rpath
14024                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14025                         error "get fid for remote directory $DIR/$rpath failed"
14026                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14027         done
14028
14029         return 0
14030 }
14031 run_test 162c "fid2path works with paths 100 or more directories deep"
14032
14033 test_169() {
14034         # do directio so as not to populate the page cache
14035         log "creating a 10 Mb file"
14036         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14037         log "starting reads"
14038         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14039         log "truncating the file"
14040         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14041         log "killing dd"
14042         kill %+ || true # reads might have finished
14043         echo "wait until dd is finished"
14044         wait
14045         log "removing the temporary file"
14046         rm -rf $DIR/$tfile || error "tmp file removal failed"
14047 }
14048 run_test 169 "parallel read and truncate should not deadlock"
14049
14050 test_170() {
14051         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14052
14053         $LCTL clear     # bug 18514
14054         $LCTL debug_daemon start $TMP/${tfile}_log_good
14055         touch $DIR/$tfile
14056         $LCTL debug_daemon stop
14057         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14058                 error "sed failed to read log_good"
14059
14060         $LCTL debug_daemon start $TMP/${tfile}_log_good
14061         rm -rf $DIR/$tfile
14062         $LCTL debug_daemon stop
14063
14064         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14065                error "lctl df log_bad failed"
14066
14067         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14068         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14069
14070         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14071         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14072
14073         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14074                 error "bad_line good_line1 good_line2 are empty"
14075
14076         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14077         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14078         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14079
14080         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14081         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14082         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14083
14084         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14085                 error "bad_line_new good_line_new are empty"
14086
14087         local expected_good=$((good_line1 + good_line2*2))
14088
14089         rm -f $TMP/${tfile}*
14090         # LU-231, short malformed line may not be counted into bad lines
14091         if [ $bad_line -ne $bad_line_new ] &&
14092                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14093                 error "expected $bad_line bad lines, but got $bad_line_new"
14094                 return 1
14095         fi
14096
14097         if [ $expected_good -ne $good_line_new ]; then
14098                 error "expected $expected_good good lines, but got $good_line_new"
14099                 return 2
14100         fi
14101         true
14102 }
14103 run_test 170 "test lctl df to handle corrupted log ====================="
14104
14105 test_171() { # bug20592
14106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14107
14108         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14109         $LCTL set_param fail_loc=0x50e
14110         $LCTL set_param fail_val=3000
14111         multiop_bg_pause $DIR/$tfile O_s || true
14112         local MULTIPID=$!
14113         kill -USR1 $MULTIPID
14114         # cause log dump
14115         sleep 3
14116         wait $MULTIPID
14117         if dmesg | grep "recursive fault"; then
14118                 error "caught a recursive fault"
14119         fi
14120         $LCTL set_param fail_loc=0
14121         true
14122 }
14123 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14124
14125 # it would be good to share it with obdfilter-survey/iokit-libecho code
14126 setup_obdecho_osc () {
14127         local rc=0
14128         local ost_nid=$1
14129         local obdfilter_name=$2
14130         echo "Creating new osc for $obdfilter_name on $ost_nid"
14131         # make sure we can find loopback nid
14132         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14133
14134         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14135                            ${obdfilter_name}_osc_UUID || rc=2; }
14136         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14137                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14138         return $rc
14139 }
14140
14141 cleanup_obdecho_osc () {
14142         local obdfilter_name=$1
14143         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14144         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14145         return 0
14146 }
14147
14148 obdecho_test() {
14149         local OBD=$1
14150         local node=$2
14151         local pages=${3:-64}
14152         local rc=0
14153         local id
14154
14155         local count=10
14156         local obd_size=$(get_obd_size $node $OBD)
14157         local page_size=$(get_page_size $node)
14158         if [[ -n "$obd_size" ]]; then
14159                 local new_count=$((obd_size / (pages * page_size / 1024)))
14160                 [[ $new_count -ge $count ]] || count=$new_count
14161         fi
14162
14163         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14164         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14165                            rc=2; }
14166         if [ $rc -eq 0 ]; then
14167             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14168             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14169         fi
14170         echo "New object id is $id"
14171         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14172                            rc=4; }
14173         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14174                            "test_brw $count w v $pages $id" || rc=4; }
14175         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14176                            rc=4; }
14177         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14178                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14179         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14180                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14181         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14182         return $rc
14183 }
14184
14185 test_180a() {
14186         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14187
14188         if ! module_loaded obdecho; then
14189                 load_module obdecho/obdecho &&
14190                         stack_trap "rmmod obdecho" EXIT ||
14191                         error "unable to load obdecho on client"
14192         fi
14193
14194         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14195         local host=$($LCTL get_param -n osc.$osc.import |
14196                      awk '/current_connection:/ { print $2 }' )
14197         local target=$($LCTL get_param -n osc.$osc.import |
14198                        awk '/target:/ { print $2 }' )
14199         target=${target%_UUID}
14200
14201         if [ -n "$target" ]; then
14202                 setup_obdecho_osc $host $target &&
14203                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14204                         { error "obdecho setup failed with $?"; return; }
14205
14206                 obdecho_test ${target}_osc client ||
14207                         error "obdecho_test failed on ${target}_osc"
14208         else
14209                 $LCTL get_param osc.$osc.import
14210                 error "there is no osc.$osc.import target"
14211         fi
14212 }
14213 run_test 180a "test obdecho on osc"
14214
14215 test_180b() {
14216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14217         remote_ost_nodsh && skip "remote OST with nodsh"
14218
14219         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14220                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14221                 error "failed to load module obdecho"
14222
14223         local target=$(do_facet ost1 $LCTL dl |
14224                        awk '/obdfilter/ { print $4; exit; }')
14225
14226         if [ -n "$target" ]; then
14227                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14228         else
14229                 do_facet ost1 $LCTL dl
14230                 error "there is no obdfilter target on ost1"
14231         fi
14232 }
14233 run_test 180b "test obdecho directly on obdfilter"
14234
14235 test_180c() { # LU-2598
14236         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14237         remote_ost_nodsh && skip "remote OST with nodsh"
14238         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14239                 skip "Need MDS version at least 2.4.0"
14240
14241         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14242                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14243                 error "failed to load module obdecho"
14244
14245         local target=$(do_facet ost1 $LCTL dl |
14246                        awk '/obdfilter/ { print $4; exit; }')
14247
14248         if [ -n "$target" ]; then
14249                 local pages=16384 # 64MB bulk I/O RPC size
14250
14251                 obdecho_test "$target" ost1 "$pages" ||
14252                         error "obdecho_test with pages=$pages failed with $?"
14253         else
14254                 do_facet ost1 $LCTL dl
14255                 error "there is no obdfilter target on ost1"
14256         fi
14257 }
14258 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14259
14260 test_181() { # bug 22177
14261         test_mkdir $DIR/$tdir
14262         # create enough files to index the directory
14263         createmany -o $DIR/$tdir/foobar 4000
14264         # print attributes for debug purpose
14265         lsattr -d .
14266         # open dir
14267         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14268         MULTIPID=$!
14269         # remove the files & current working dir
14270         unlinkmany $DIR/$tdir/foobar 4000
14271         rmdir $DIR/$tdir
14272         kill -USR1 $MULTIPID
14273         wait $MULTIPID
14274         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14275         return 0
14276 }
14277 run_test 181 "Test open-unlinked dir ========================"
14278
14279 test_182() {
14280         local fcount=1000
14281         local tcount=10
14282
14283         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14284
14285         $LCTL set_param mdc.*.rpc_stats=clear
14286
14287         for (( i = 0; i < $tcount; i++ )) ; do
14288                 mkdir $DIR/$tdir/$i
14289         done
14290
14291         for (( i = 0; i < $tcount; i++ )) ; do
14292                 createmany -o $DIR/$tdir/$i/f- $fcount &
14293         done
14294         wait
14295
14296         for (( i = 0; i < $tcount; i++ )) ; do
14297                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14298         done
14299         wait
14300
14301         $LCTL get_param mdc.*.rpc_stats
14302
14303         rm -rf $DIR/$tdir
14304 }
14305 run_test 182 "Test parallel modify metadata operations ================"
14306
14307 test_183() { # LU-2275
14308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14309         remote_mds_nodsh && skip "remote MDS with nodsh"
14310         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14311                 skip "Need MDS version at least 2.3.56"
14312
14313         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14314         echo aaa > $DIR/$tdir/$tfile
14315
14316 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14317         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14318
14319         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14320         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14321
14322         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14323
14324         # Flush negative dentry cache
14325         touch $DIR/$tdir/$tfile
14326
14327         # We are not checking for any leaked references here, they'll
14328         # become evident next time we do cleanup with module unload.
14329         rm -rf $DIR/$tdir
14330 }
14331 run_test 183 "No crash or request leak in case of strange dispositions ========"
14332
14333 # test suite 184 is for LU-2016, LU-2017
14334 test_184a() {
14335         check_swap_layouts_support
14336
14337         dir0=$DIR/$tdir/$testnum
14338         test_mkdir -p -c1 $dir0
14339         ref1=/etc/passwd
14340         ref2=/etc/group
14341         file1=$dir0/f1
14342         file2=$dir0/f2
14343         $LFS setstripe -c1 $file1
14344         cp $ref1 $file1
14345         $LFS setstripe -c2 $file2
14346         cp $ref2 $file2
14347         gen1=$($LFS getstripe -g $file1)
14348         gen2=$($LFS getstripe -g $file2)
14349
14350         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14351         gen=$($LFS getstripe -g $file1)
14352         [[ $gen1 != $gen ]] ||
14353                 "Layout generation on $file1 does not change"
14354         gen=$($LFS getstripe -g $file2)
14355         [[ $gen2 != $gen ]] ||
14356                 "Layout generation on $file2 does not change"
14357
14358         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14359         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14360
14361         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14362 }
14363 run_test 184a "Basic layout swap"
14364
14365 test_184b() {
14366         check_swap_layouts_support
14367
14368         dir0=$DIR/$tdir/$testnum
14369         mkdir -p $dir0 || error "creating dir $dir0"
14370         file1=$dir0/f1
14371         file2=$dir0/f2
14372         file3=$dir0/f3
14373         dir1=$dir0/d1
14374         dir2=$dir0/d2
14375         mkdir $dir1 $dir2
14376         $LFS setstripe -c1 $file1
14377         $LFS setstripe -c2 $file2
14378         $LFS setstripe -c1 $file3
14379         chown $RUNAS_ID $file3
14380         gen1=$($LFS getstripe -g $file1)
14381         gen2=$($LFS getstripe -g $file2)
14382
14383         $LFS swap_layouts $dir1 $dir2 &&
14384                 error "swap of directories layouts should fail"
14385         $LFS swap_layouts $dir1 $file1 &&
14386                 error "swap of directory and file layouts should fail"
14387         $RUNAS $LFS swap_layouts $file1 $file2 &&
14388                 error "swap of file we cannot write should fail"
14389         $LFS swap_layouts $file1 $file3 &&
14390                 error "swap of file with different owner should fail"
14391         /bin/true # to clear error code
14392 }
14393 run_test 184b "Forbidden layout swap (will generate errors)"
14394
14395 test_184c() {
14396         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14397         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14398         check_swap_layouts_support
14399
14400         local dir0=$DIR/$tdir/$testnum
14401         mkdir -p $dir0 || error "creating dir $dir0"
14402
14403         local ref1=$dir0/ref1
14404         local ref2=$dir0/ref2
14405         local file1=$dir0/file1
14406         local file2=$dir0/file2
14407         # create a file large enough for the concurrent test
14408         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14409         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14410         echo "ref file size: ref1($(stat -c %s $ref1))," \
14411              "ref2($(stat -c %s $ref2))"
14412
14413         cp $ref2 $file2
14414         dd if=$ref1 of=$file1 bs=16k &
14415         local DD_PID=$!
14416
14417         # Make sure dd starts to copy file
14418         while [ ! -f $file1 ]; do sleep 0.1; done
14419
14420         $LFS swap_layouts $file1 $file2
14421         local rc=$?
14422         wait $DD_PID
14423         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14424         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14425
14426         # how many bytes copied before swapping layout
14427         local copied=$(stat -c %s $file2)
14428         local remaining=$(stat -c %s $ref1)
14429         remaining=$((remaining - copied))
14430         echo "Copied $copied bytes before swapping layout..."
14431
14432         cmp -n $copied $file1 $ref2 | grep differ &&
14433                 error "Content mismatch [0, $copied) of ref2 and file1"
14434         cmp -n $copied $file2 $ref1 ||
14435                 error "Content mismatch [0, $copied) of ref1 and file2"
14436         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14437                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14438
14439         # clean up
14440         rm -f $ref1 $ref2 $file1 $file2
14441 }
14442 run_test 184c "Concurrent write and layout swap"
14443
14444 test_184d() {
14445         check_swap_layouts_support
14446         [ -z "$(which getfattr 2>/dev/null)" ] &&
14447                 skip_env "no getfattr command"
14448
14449         local file1=$DIR/$tdir/$tfile-1
14450         local file2=$DIR/$tdir/$tfile-2
14451         local file3=$DIR/$tdir/$tfile-3
14452         local lovea1
14453         local lovea2
14454
14455         mkdir -p $DIR/$tdir
14456         touch $file1 || error "create $file1 failed"
14457         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14458                 error "create $file2 failed"
14459         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14460                 error "create $file3 failed"
14461         lovea1=$(get_layout_param $file1)
14462
14463         $LFS swap_layouts $file2 $file3 ||
14464                 error "swap $file2 $file3 layouts failed"
14465         $LFS swap_layouts $file1 $file2 ||
14466                 error "swap $file1 $file2 layouts failed"
14467
14468         lovea2=$(get_layout_param $file2)
14469         echo "$lovea1"
14470         echo "$lovea2"
14471         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14472
14473         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14474         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14475 }
14476 run_test 184d "allow stripeless layouts swap"
14477
14478 test_184e() {
14479         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14480                 skip "Need MDS version at least 2.6.94"
14481         check_swap_layouts_support
14482         [ -z "$(which getfattr 2>/dev/null)" ] &&
14483                 skip_env "no getfattr command"
14484
14485         local file1=$DIR/$tdir/$tfile-1
14486         local file2=$DIR/$tdir/$tfile-2
14487         local file3=$DIR/$tdir/$tfile-3
14488         local lovea
14489
14490         mkdir -p $DIR/$tdir
14491         touch $file1 || error "create $file1 failed"
14492         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14493                 error "create $file2 failed"
14494         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14495                 error "create $file3 failed"
14496
14497         $LFS swap_layouts $file1 $file2 ||
14498                 error "swap $file1 $file2 layouts failed"
14499
14500         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14501         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14502
14503         echo 123 > $file1 || error "Should be able to write into $file1"
14504
14505         $LFS swap_layouts $file1 $file3 ||
14506                 error "swap $file1 $file3 layouts failed"
14507
14508         echo 123 > $file1 || error "Should be able to write into $file1"
14509
14510         rm -rf $file1 $file2 $file3
14511 }
14512 run_test 184e "Recreate layout after stripeless layout swaps"
14513
14514 test_184f() {
14515         # Create a file with name longer than sizeof(struct stat) ==
14516         # 144 to see if we can get chars from the file name to appear
14517         # in the returned striping. Note that 'f' == 0x66.
14518         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14519
14520         mkdir -p $DIR/$tdir
14521         mcreate $DIR/$tdir/$file
14522         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14523                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14524         fi
14525 }
14526 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14527
14528 test_185() { # LU-2441
14529         # LU-3553 - no volatile file support in old servers
14530         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14531                 skip "Need MDS version at least 2.3.60"
14532
14533         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14534         touch $DIR/$tdir/spoo
14535         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14536         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14537                 error "cannot create/write a volatile file"
14538         [ "$FILESET" == "" ] &&
14539         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14540                 error "FID is still valid after close"
14541
14542         multiop_bg_pause $DIR/$tdir vVw4096_c
14543         local multi_pid=$!
14544
14545         local OLD_IFS=$IFS
14546         IFS=":"
14547         local fidv=($fid)
14548         IFS=$OLD_IFS
14549         # assume that the next FID for this client is sequential, since stdout
14550         # is unfortunately eaten by multiop_bg_pause
14551         local n=$((${fidv[1]} + 1))
14552         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14553         if [ "$FILESET" == "" ]; then
14554                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14555                         error "FID is missing before close"
14556         fi
14557         kill -USR1 $multi_pid
14558         # 1 second delay, so if mtime change we will see it
14559         sleep 1
14560         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14561         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14562 }
14563 run_test 185 "Volatile file support"
14564
14565 function create_check_volatile() {
14566         local idx=$1
14567         local tgt
14568
14569         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
14570         local PID=$!
14571         sleep 1
14572         local FID=$(cat /tmp/${tfile}.fid)
14573         [ "$FID" == "" ] && error "can't get FID for volatile"
14574         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
14575         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
14576         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
14577         kill -USR1 $PID
14578         wait
14579         sleep 1
14580         cancel_lru_locks mdc # flush opencache
14581         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
14582         return 0
14583 }
14584
14585 test_185a(){
14586         # LU-12516 - volatile creation via .lustre
14587         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
14588                 skip "Need MDS version at least 2.3.55"
14589
14590         create_check_volatile 0
14591         [ $MDSCOUNT -lt 2 ] && return 0
14592
14593         # DNE case
14594         create_check_volatile 1
14595
14596         return 0
14597 }
14598 run_test 185a "Volatile file creation in .lustre/fid/"
14599
14600 test_187a() {
14601         remote_mds_nodsh && skip "remote MDS with nodsh"
14602         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14603                 skip "Need MDS version at least 2.3.0"
14604
14605         local dir0=$DIR/$tdir/$testnum
14606         mkdir -p $dir0 || error "creating dir $dir0"
14607
14608         local file=$dir0/file1
14609         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14610         local dv1=$($LFS data_version $file)
14611         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14612         local dv2=$($LFS data_version $file)
14613         [[ $dv1 != $dv2 ]] ||
14614                 error "data version did not change on write $dv1 == $dv2"
14615
14616         # clean up
14617         rm -f $file1
14618 }
14619 run_test 187a "Test data version change"
14620
14621 test_187b() {
14622         remote_mds_nodsh && skip "remote MDS with nodsh"
14623         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14624                 skip "Need MDS version at least 2.3.0"
14625
14626         local dir0=$DIR/$tdir/$testnum
14627         mkdir -p $dir0 || error "creating dir $dir0"
14628
14629         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14630         [[ ${DV[0]} != ${DV[1]} ]] ||
14631                 error "data version did not change on write"\
14632                       " ${DV[0]} == ${DV[1]}"
14633
14634         # clean up
14635         rm -f $file1
14636 }
14637 run_test 187b "Test data version change on volatile file"
14638
14639 test_200() {
14640         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14641         remote_mgs_nodsh && skip "remote MGS with nodsh"
14642         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14643
14644         local POOL=${POOL:-cea1}
14645         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14646         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14647         # Pool OST targets
14648         local first_ost=0
14649         local last_ost=$(($OSTCOUNT - 1))
14650         local ost_step=2
14651         local ost_list=$(seq $first_ost $ost_step $last_ost)
14652         local ost_range="$first_ost $last_ost $ost_step"
14653         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14654         local file_dir=$POOL_ROOT/file_tst
14655         local subdir=$test_path/subdir
14656         local rc=0
14657
14658         if ! combined_mgs_mds ; then
14659                 mount_mgs_client
14660         fi
14661
14662         while : ; do
14663                 # former test_200a test_200b
14664                 pool_add $POOL                          || { rc=$? ; break; }
14665                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14666                 # former test_200c test_200d
14667                 mkdir -p $test_path
14668                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14669                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14670                 mkdir -p $subdir
14671                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14672                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14673                                                         || { rc=$? ; break; }
14674                 # former test_200e test_200f
14675                 local files=$((OSTCOUNT*3))
14676                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14677                                                         || { rc=$? ; break; }
14678                 pool_create_files $POOL $file_dir $files "$ost_list" \
14679                                                         || { rc=$? ; break; }
14680                 # former test_200g test_200h
14681                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14682                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14683
14684                 # former test_201a test_201b test_201c
14685                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14686
14687                 local f=$test_path/$tfile
14688                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14689                 pool_remove $POOL $f                    || { rc=$? ; break; }
14690                 break
14691         done
14692
14693         destroy_test_pools
14694
14695         if ! combined_mgs_mds ; then
14696                 umount_mgs_client
14697         fi
14698         return $rc
14699 }
14700 run_test 200 "OST pools"
14701
14702 # usage: default_attr <count | size | offset>
14703 default_attr() {
14704         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14705 }
14706
14707 # usage: check_default_stripe_attr
14708 check_default_stripe_attr() {
14709         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14710         case $1 in
14711         --stripe-count|-c)
14712                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14713         --stripe-size|-S)
14714                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14715         --stripe-index|-i)
14716                 EXPECTED=-1;;
14717         *)
14718                 error "unknown getstripe attr '$1'"
14719         esac
14720
14721         [ $ACTUAL == $EXPECTED ] ||
14722                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14723 }
14724
14725 test_204a() {
14726         test_mkdir $DIR/$tdir
14727         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14728
14729         check_default_stripe_attr --stripe-count
14730         check_default_stripe_attr --stripe-size
14731         check_default_stripe_attr --stripe-index
14732 }
14733 run_test 204a "Print default stripe attributes"
14734
14735 test_204b() {
14736         test_mkdir $DIR/$tdir
14737         $LFS setstripe --stripe-count 1 $DIR/$tdir
14738
14739         check_default_stripe_attr --stripe-size
14740         check_default_stripe_attr --stripe-index
14741 }
14742 run_test 204b "Print default stripe size and offset"
14743
14744 test_204c() {
14745         test_mkdir $DIR/$tdir
14746         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14747
14748         check_default_stripe_attr --stripe-count
14749         check_default_stripe_attr --stripe-index
14750 }
14751 run_test 204c "Print default stripe count and offset"
14752
14753 test_204d() {
14754         test_mkdir $DIR/$tdir
14755         $LFS setstripe --stripe-index 0 $DIR/$tdir
14756
14757         check_default_stripe_attr --stripe-count
14758         check_default_stripe_attr --stripe-size
14759 }
14760 run_test 204d "Print default stripe count and size"
14761
14762 test_204e() {
14763         test_mkdir $DIR/$tdir
14764         $LFS setstripe -d $DIR/$tdir
14765
14766         check_default_stripe_attr --stripe-count --raw
14767         check_default_stripe_attr --stripe-size --raw
14768         check_default_stripe_attr --stripe-index --raw
14769 }
14770 run_test 204e "Print raw stripe attributes"
14771
14772 test_204f() {
14773         test_mkdir $DIR/$tdir
14774         $LFS setstripe --stripe-count 1 $DIR/$tdir
14775
14776         check_default_stripe_attr --stripe-size --raw
14777         check_default_stripe_attr --stripe-index --raw
14778 }
14779 run_test 204f "Print raw stripe size and offset"
14780
14781 test_204g() {
14782         test_mkdir $DIR/$tdir
14783         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14784
14785         check_default_stripe_attr --stripe-count --raw
14786         check_default_stripe_attr --stripe-index --raw
14787 }
14788 run_test 204g "Print raw stripe count and offset"
14789
14790 test_204h() {
14791         test_mkdir $DIR/$tdir
14792         $LFS setstripe --stripe-index 0 $DIR/$tdir
14793
14794         check_default_stripe_attr --stripe-count --raw
14795         check_default_stripe_attr --stripe-size --raw
14796 }
14797 run_test 204h "Print raw stripe count and size"
14798
14799 # Figure out which job scheduler is being used, if any,
14800 # or use a fake one
14801 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
14802         JOBENV=SLURM_JOB_ID
14803 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
14804         JOBENV=LSB_JOBID
14805 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
14806         JOBENV=PBS_JOBID
14807 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
14808         JOBENV=LOADL_STEP_ID
14809 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
14810         JOBENV=JOB_ID
14811 else
14812         $LCTL list_param jobid_name > /dev/null 2>&1
14813         if [ $? -eq 0 ]; then
14814                 JOBENV=nodelocal
14815         else
14816                 JOBENV=FAKE_JOBID
14817         fi
14818 fi
14819 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
14820
14821 verify_jobstats() {
14822         local cmd=($1)
14823         shift
14824         local facets="$@"
14825
14826 # we don't really need to clear the stats for this test to work, since each
14827 # command has a unique jobid, but it makes debugging easier if needed.
14828 #       for facet in $facets; do
14829 #               local dev=$(convert_facet2label $facet)
14830 #               # clear old jobstats
14831 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
14832 #       done
14833
14834         # use a new JobID for each test, or we might see an old one
14835         [ "$JOBENV" = "FAKE_JOBID" ] &&
14836                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
14837
14838         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
14839
14840         [ "$JOBENV" = "nodelocal" ] && {
14841                 FAKE_JOBID=id.$testnum.%e.$RANDOM
14842                 $LCTL set_param jobid_name=$FAKE_JOBID
14843                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
14844         }
14845
14846         log "Test: ${cmd[*]}"
14847         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
14848
14849         if [ $JOBENV = "FAKE_JOBID" ]; then
14850                 FAKE_JOBID=$JOBVAL ${cmd[*]}
14851         else
14852                 ${cmd[*]}
14853         fi
14854
14855         # all files are created on OST0000
14856         for facet in $facets; do
14857                 local stats="*.$(convert_facet2label $facet).job_stats"
14858
14859                 # strip out libtool wrappers for in-tree executables
14860                 if [ $(do_facet $facet lctl get_param $stats |
14861                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
14862                         do_facet $facet lctl get_param $stats
14863                         error "No jobstats for $JOBVAL found on $facet::$stats"
14864                 fi
14865         done
14866 }
14867
14868 jobstats_set() {
14869         local new_jobenv=$1
14870
14871         set_persistent_param_and_check client "jobid_var" \
14872                 "$FSNAME.sys.jobid_var" $new_jobenv
14873 }
14874
14875 test_205() { # Job stats
14876         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14877         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
14878                 skip "Need MDS version with at least 2.7.1"
14879         remote_mgs_nodsh && skip "remote MGS with nodsh"
14880         remote_mds_nodsh && skip "remote MDS with nodsh"
14881         remote_ost_nodsh && skip "remote OST with nodsh"
14882         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
14883                 skip "Server doesn't support jobstats"
14884         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
14885
14886         local old_jobenv=$($LCTL get_param -n jobid_var)
14887         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
14888
14889         if [[ $PERM_CMD == *"set_param -P"* ]]; then
14890                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
14891         else
14892                 stack_trap "do_facet mgs $PERM_CMD \
14893                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
14894         fi
14895         changelog_register
14896
14897         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
14898                                 mdt.*.job_cleanup_interval | head -n 1)
14899         local new_interval=5
14900         do_facet $SINGLEMDS \
14901                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
14902         stack_trap "do_facet $SINGLEMDS \
14903                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
14904         local start=$SECONDS
14905
14906         local cmd
14907         # mkdir
14908         cmd="mkdir $DIR/$tdir"
14909         verify_jobstats "$cmd" "$SINGLEMDS"
14910         # rmdir
14911         cmd="rmdir $DIR/$tdir"
14912         verify_jobstats "$cmd" "$SINGLEMDS"
14913         # mkdir on secondary MDT
14914         if [ $MDSCOUNT -gt 1 ]; then
14915                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
14916                 verify_jobstats "$cmd" "mds2"
14917         fi
14918         # mknod
14919         cmd="mknod $DIR/$tfile c 1 3"
14920         verify_jobstats "$cmd" "$SINGLEMDS"
14921         # unlink
14922         cmd="rm -f $DIR/$tfile"
14923         verify_jobstats "$cmd" "$SINGLEMDS"
14924         # create all files on OST0000 so verify_jobstats can find OST stats
14925         # open & close
14926         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
14927         verify_jobstats "$cmd" "$SINGLEMDS"
14928         # setattr
14929         cmd="touch $DIR/$tfile"
14930         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14931         # write
14932         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
14933         verify_jobstats "$cmd" "ost1"
14934         # read
14935         cancel_lru_locks osc
14936         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
14937         verify_jobstats "$cmd" "ost1"
14938         # truncate
14939         cmd="$TRUNCATE $DIR/$tfile 0"
14940         verify_jobstats "$cmd" "$SINGLEMDS ost1"
14941         # rename
14942         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
14943         verify_jobstats "$cmd" "$SINGLEMDS"
14944         # jobstats expiry - sleep until old stats should be expired
14945         local left=$((new_interval + 5 - (SECONDS - start)))
14946         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
14947                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
14948                         "0" $left
14949         cmd="mkdir $DIR/$tdir.expire"
14950         verify_jobstats "$cmd" "$SINGLEMDS"
14951         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
14952             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
14953
14954         # Ensure that jobid are present in changelog (if supported by MDS)
14955         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
14956                 changelog_dump | tail -10
14957                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
14958                 [ $jobids -eq 9 ] ||
14959                         error "Wrong changelog jobid count $jobids != 9"
14960
14961                 # LU-5862
14962                 JOBENV="disable"
14963                 jobstats_set $JOBENV
14964                 touch $DIR/$tfile
14965                 changelog_dump | grep $tfile
14966                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
14967                 [ $jobids -eq 0 ] ||
14968                         error "Unexpected jobids when jobid_var=$JOBENV"
14969         fi
14970
14971         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
14972         JOBENV="JOBCOMPLEX"
14973         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
14974
14975         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
14976 }
14977 run_test 205 "Verify job stats"
14978
14979 # LU-1480, LU-1773 and LU-1657
14980 test_206() {
14981         mkdir -p $DIR/$tdir
14982         $LFS setstripe -c -1 $DIR/$tdir
14983 #define OBD_FAIL_LOV_INIT 0x1403
14984         $LCTL set_param fail_loc=0xa0001403
14985         $LCTL set_param fail_val=1
14986         touch $DIR/$tdir/$tfile || true
14987 }
14988 run_test 206 "fail lov_init_raid0() doesn't lbug"
14989
14990 test_207a() {
14991         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
14992         local fsz=`stat -c %s $DIR/$tfile`
14993         cancel_lru_locks mdc
14994
14995         # do not return layout in getattr intent
14996 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
14997         $LCTL set_param fail_loc=0x170
14998         local sz=`stat -c %s $DIR/$tfile`
14999
15000         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15001
15002         rm -rf $DIR/$tfile
15003 }
15004 run_test 207a "can refresh layout at glimpse"
15005
15006 test_207b() {
15007         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15008         local cksum=`md5sum $DIR/$tfile`
15009         local fsz=`stat -c %s $DIR/$tfile`
15010         cancel_lru_locks mdc
15011         cancel_lru_locks osc
15012
15013         # do not return layout in getattr intent
15014 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15015         $LCTL set_param fail_loc=0x171
15016
15017         # it will refresh layout after the file is opened but before read issues
15018         echo checksum is "$cksum"
15019         echo "$cksum" |md5sum -c --quiet || error "file differs"
15020
15021         rm -rf $DIR/$tfile
15022 }
15023 run_test 207b "can refresh layout at open"
15024
15025 test_208() {
15026         # FIXME: in this test suite, only RD lease is used. This is okay
15027         # for now as only exclusive open is supported. After generic lease
15028         # is done, this test suite should be revised. - Jinshan
15029
15030         remote_mds_nodsh && skip "remote MDS with nodsh"
15031         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15032                 skip "Need MDS version at least 2.4.52"
15033
15034         echo "==== test 1: verify get lease work"
15035         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15036
15037         echo "==== test 2: verify lease can be broken by upcoming open"
15038         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15039         local PID=$!
15040         sleep 1
15041
15042         $MULTIOP $DIR/$tfile oO_RDONLY:c
15043         kill -USR1 $PID && wait $PID || error "break lease error"
15044
15045         echo "==== test 3: verify lease can't be granted if an open already exists"
15046         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15047         local PID=$!
15048         sleep 1
15049
15050         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15051         kill -USR1 $PID && wait $PID || error "open file error"
15052
15053         echo "==== test 4: lease can sustain over recovery"
15054         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15055         PID=$!
15056         sleep 1
15057
15058         fail mds1
15059
15060         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15061
15062         echo "==== test 5: lease broken can't be regained by replay"
15063         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15064         PID=$!
15065         sleep 1
15066
15067         # open file to break lease and then recovery
15068         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15069         fail mds1
15070
15071         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15072
15073         rm -f $DIR/$tfile
15074 }
15075 run_test 208 "Exclusive open"
15076
15077 test_209() {
15078         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15079                 skip_env "must have disp_stripe"
15080
15081         touch $DIR/$tfile
15082         sync; sleep 5; sync;
15083
15084         echo 3 > /proc/sys/vm/drop_caches
15085         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15086
15087         # open/close 500 times
15088         for i in $(seq 500); do
15089                 cat $DIR/$tfile
15090         done
15091
15092         echo 3 > /proc/sys/vm/drop_caches
15093         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15094
15095         echo "before: $req_before, after: $req_after"
15096         [ $((req_after - req_before)) -ge 300 ] &&
15097                 error "open/close requests are not freed"
15098         return 0
15099 }
15100 run_test 209 "read-only open/close requests should be freed promptly"
15101
15102 test_212() {
15103         size=`date +%s`
15104         size=$((size % 8192 + 1))
15105         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15106         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15107         rm -f $DIR/f212 $DIR/f212.xyz
15108 }
15109 run_test 212 "Sendfile test ============================================"
15110
15111 test_213() {
15112         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15113         cancel_lru_locks osc
15114         lctl set_param fail_loc=0x8000040f
15115         # generate a read lock
15116         cat $DIR/$tfile > /dev/null
15117         # write to the file, it will try to cancel the above read lock.
15118         cat /etc/hosts >> $DIR/$tfile
15119 }
15120 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15121
15122 test_214() { # for bug 20133
15123         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15124         for (( i=0; i < 340; i++ )) ; do
15125                 touch $DIR/$tdir/d214c/a$i
15126         done
15127
15128         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15129         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15130         ls $DIR/d214c || error "ls $DIR/d214c failed"
15131         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15132         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15133 }
15134 run_test 214 "hash-indexed directory test - bug 20133"
15135
15136 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15137 create_lnet_proc_files() {
15138         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15139 }
15140
15141 # counterpart of create_lnet_proc_files
15142 remove_lnet_proc_files() {
15143         rm -f $TMP/lnet_$1.sys
15144 }
15145
15146 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15147 # 3rd arg as regexp for body
15148 check_lnet_proc_stats() {
15149         local l=$(cat "$TMP/lnet_$1" |wc -l)
15150         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15151
15152         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15153 }
15154
15155 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15156 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15157 # optional and can be regexp for 2nd line (lnet.routes case)
15158 check_lnet_proc_entry() {
15159         local blp=2          # blp stands for 'position of 1st line of body'
15160         [ -z "$5" ] || blp=3 # lnet.routes case
15161
15162         local l=$(cat "$TMP/lnet_$1" |wc -l)
15163         # subtracting one from $blp because the body can be empty
15164         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15165
15166         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15167                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15168
15169         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15170                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15171
15172         # bail out if any unexpected line happened
15173         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15174         [ "$?" != 0 ] || error "$2 misformatted"
15175 }
15176
15177 test_215() { # for bugs 18102, 21079, 21517
15178         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15179
15180         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15181         local P='[1-9][0-9]*'           # positive numeric
15182         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15183         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15184         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15185         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15186
15187         local L1 # regexp for 1st line
15188         local L2 # regexp for 2nd line (optional)
15189         local BR # regexp for the rest (body)
15190
15191         # lnet.stats should look as 11 space-separated non-negative numerics
15192         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15193         create_lnet_proc_files "stats"
15194         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15195         remove_lnet_proc_files "stats"
15196
15197         # lnet.routes should look like this:
15198         # Routing disabled/enabled
15199         # net hops priority state router
15200         # where net is a string like tcp0, hops > 0, priority >= 0,
15201         # state is up/down,
15202         # router is a string like 192.168.1.1@tcp2
15203         L1="^Routing (disabled|enabled)$"
15204         L2="^net +hops +priority +state +router$"
15205         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15206         create_lnet_proc_files "routes"
15207         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15208         remove_lnet_proc_files "routes"
15209
15210         # lnet.routers should look like this:
15211         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15212         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15213         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15214         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15215         L1="^ref +rtr_ref +alive +router$"
15216         BR="^$P +$P +(up|down) +$NID$"
15217         create_lnet_proc_files "routers"
15218         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15219         remove_lnet_proc_files "routers"
15220
15221         # lnet.peers should look like this:
15222         # nid refs state last max rtr min tx min queue
15223         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15224         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15225         # numeric (0 or >0 or <0), queue >= 0.
15226         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15227         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15228         create_lnet_proc_files "peers"
15229         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15230         remove_lnet_proc_files "peers"
15231
15232         # lnet.buffers  should look like this:
15233         # pages count credits min
15234         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15235         L1="^pages +count +credits +min$"
15236         BR="^ +$N +$N +$I +$I$"
15237         create_lnet_proc_files "buffers"
15238         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15239         remove_lnet_proc_files "buffers"
15240
15241         # lnet.nis should look like this:
15242         # nid status alive refs peer rtr max tx min
15243         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15244         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15245         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15246         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15247         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15248         create_lnet_proc_files "nis"
15249         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15250         remove_lnet_proc_files "nis"
15251
15252         # can we successfully write to lnet.stats?
15253         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15254 }
15255 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15256
15257 test_216() { # bug 20317
15258         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15259         remote_ost_nodsh && skip "remote OST with nodsh"
15260
15261         local node
15262         local facets=$(get_facets OST)
15263         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15264
15265         save_lustre_params client "osc.*.contention_seconds" > $p
15266         save_lustre_params $facets \
15267                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15268         save_lustre_params $facets \
15269                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15270         save_lustre_params $facets \
15271                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15272         clear_stats osc.*.osc_stats
15273
15274         # agressive lockless i/o settings
15275         do_nodes $(comma_list $(osts_nodes)) \
15276                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15277                         ldlm.namespaces.filter-*.contended_locks=0 \
15278                         ldlm.namespaces.filter-*.contention_seconds=60"
15279         lctl set_param -n osc.*.contention_seconds=60
15280
15281         $DIRECTIO write $DIR/$tfile 0 10 4096
15282         $CHECKSTAT -s 40960 $DIR/$tfile
15283
15284         # disable lockless i/o
15285         do_nodes $(comma_list $(osts_nodes)) \
15286                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15287                         ldlm.namespaces.filter-*.contended_locks=32 \
15288                         ldlm.namespaces.filter-*.contention_seconds=0"
15289         lctl set_param -n osc.*.contention_seconds=0
15290         clear_stats osc.*.osc_stats
15291
15292         dd if=/dev/zero of=$DIR/$tfile count=0
15293         $CHECKSTAT -s 0 $DIR/$tfile
15294
15295         restore_lustre_params <$p
15296         rm -f $p
15297         rm $DIR/$tfile
15298 }
15299 run_test 216 "check lockless direct write updates file size and kms correctly"
15300
15301 test_217() { # bug 22430
15302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15303
15304         local node
15305         local nid
15306
15307         for node in $(nodes_list); do
15308                 nid=$(host_nids_address $node $NETTYPE)
15309                 if [[ $nid = *-* ]] ; then
15310                         echo "lctl ping $(h2nettype $nid)"
15311                         lctl ping $(h2nettype $nid)
15312                 else
15313                         echo "skipping $node (no hyphen detected)"
15314                 fi
15315         done
15316 }
15317 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15318
15319 test_218() {
15320        # do directio so as not to populate the page cache
15321        log "creating a 10 Mb file"
15322        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15323        log "starting reads"
15324        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15325        log "truncating the file"
15326        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15327        log "killing dd"
15328        kill %+ || true # reads might have finished
15329        echo "wait until dd is finished"
15330        wait
15331        log "removing the temporary file"
15332        rm -rf $DIR/$tfile || error "tmp file removal failed"
15333 }
15334 run_test 218 "parallel read and truncate should not deadlock"
15335
15336 test_219() {
15337         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15338
15339         # write one partial page
15340         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15341         # set no grant so vvp_io_commit_write will do sync write
15342         $LCTL set_param fail_loc=0x411
15343         # write a full page at the end of file
15344         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15345
15346         $LCTL set_param fail_loc=0
15347         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15348         $LCTL set_param fail_loc=0x411
15349         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15350
15351         # LU-4201
15352         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15353         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15354 }
15355 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15356
15357 test_220() { #LU-325
15358         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15359         remote_ost_nodsh && skip "remote OST with nodsh"
15360         remote_mds_nodsh && skip "remote MDS with nodsh"
15361         remote_mgs_nodsh && skip "remote MGS with nodsh"
15362
15363         local OSTIDX=0
15364
15365         # create on MDT0000 so the last_id and next_id are correct
15366         mkdir $DIR/$tdir
15367         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15368         OST=${OST%_UUID}
15369
15370         # on the mdt's osc
15371         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15372         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15373                         osp.$mdtosc_proc1.prealloc_last_id)
15374         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15375                         osp.$mdtosc_proc1.prealloc_next_id)
15376
15377         $LFS df -i
15378
15379         if ! combined_mgs_mds ; then
15380                 mount_mgs_client
15381         fi
15382
15383         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15384         #define OBD_FAIL_OST_ENOINO              0x229
15385         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15386         create_pool $FSNAME.$TESTNAME || return 1
15387         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15388
15389         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15390
15391         MDSOBJS=$((last_id - next_id))
15392         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15393
15394         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15395         echo "OST still has $count kbytes free"
15396
15397         echo "create $MDSOBJS files @next_id..."
15398         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15399
15400         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15401                         osp.$mdtosc_proc1.prealloc_last_id)
15402         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15403                         osp.$mdtosc_proc1.prealloc_next_id)
15404
15405         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15406         $LFS df -i
15407
15408         echo "cleanup..."
15409
15410         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15411         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15412
15413         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15414                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15415         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15416                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15417         echo "unlink $MDSOBJS files @$next_id..."
15418         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15419
15420         if ! combined_mgs_mds ; then
15421                 umount_mgs_client
15422         fi
15423 }
15424 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15425
15426 test_221() {
15427         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15428
15429         dd if=`which date` of=$MOUNT/date oflag=sync
15430         chmod +x $MOUNT/date
15431
15432         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15433         $LCTL set_param fail_loc=0x80001401
15434
15435         $MOUNT/date > /dev/null
15436         rm -f $MOUNT/date
15437 }
15438 run_test 221 "make sure fault and truncate race to not cause OOM"
15439
15440 test_222a () {
15441         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15442
15443         rm -rf $DIR/$tdir
15444         test_mkdir $DIR/$tdir
15445         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15446         createmany -o $DIR/$tdir/$tfile 10
15447         cancel_lru_locks mdc
15448         cancel_lru_locks osc
15449         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15450         $LCTL set_param fail_loc=0x31a
15451         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15452         $LCTL set_param fail_loc=0
15453         rm -r $DIR/$tdir
15454 }
15455 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15456
15457 test_222b () {
15458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15459
15460         rm -rf $DIR/$tdir
15461         test_mkdir $DIR/$tdir
15462         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15463         createmany -o $DIR/$tdir/$tfile 10
15464         cancel_lru_locks mdc
15465         cancel_lru_locks osc
15466         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15467         $LCTL set_param fail_loc=0x31a
15468         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15469         $LCTL set_param fail_loc=0
15470 }
15471 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15472
15473 test_223 () {
15474         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15475
15476         rm -rf $DIR/$tdir
15477         test_mkdir $DIR/$tdir
15478         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15479         createmany -o $DIR/$tdir/$tfile 10
15480         cancel_lru_locks mdc
15481         cancel_lru_locks osc
15482         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15483         $LCTL set_param fail_loc=0x31b
15484         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15485         $LCTL set_param fail_loc=0
15486         rm -r $DIR/$tdir
15487 }
15488 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15489
15490 test_224a() { # LU-1039, MRP-303
15491         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15492
15493         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15494         $LCTL set_param fail_loc=0x508
15495         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15496         $LCTL set_param fail_loc=0
15497         df $DIR
15498 }
15499 run_test 224a "Don't panic on bulk IO failure"
15500
15501 test_224b() { # LU-1039, MRP-303
15502         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15503
15504         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15505         cancel_lru_locks osc
15506         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15507         $LCTL set_param fail_loc=0x515
15508         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15509         $LCTL set_param fail_loc=0
15510         df $DIR
15511 }
15512 run_test 224b "Don't panic on bulk IO failure"
15513
15514 test_224c() { # LU-6441
15515         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15516         remote_mds_nodsh && skip "remote MDS with nodsh"
15517
15518         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15519         save_writethrough $p
15520         set_cache writethrough on
15521
15522         local pages_per_rpc=$($LCTL get_param \
15523                                 osc.*.max_pages_per_rpc)
15524         local at_max=$($LCTL get_param -n at_max)
15525         local timeout=$($LCTL get_param -n timeout)
15526         local test_at="at_max"
15527         local param_at="$FSNAME.sys.at_max"
15528         local test_timeout="timeout"
15529         local param_timeout="$FSNAME.sys.timeout"
15530
15531         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15532
15533         set_persistent_param_and_check client "$test_at" "$param_at" 0
15534         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15535
15536         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15537         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15538         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15539         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15540         sync
15541         do_facet ost1 "$LCTL set_param fail_loc=0"
15542
15543         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15544         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15545                 $timeout
15546
15547         $LCTL set_param -n $pages_per_rpc
15548         restore_lustre_params < $p
15549         rm -f $p
15550 }
15551 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15552
15553 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15554 test_225a () {
15555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15556         if [ -z ${MDSSURVEY} ]; then
15557                 skip_env "mds-survey not found"
15558         fi
15559         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15560                 skip "Need MDS version at least 2.2.51"
15561
15562         local mds=$(facet_host $SINGLEMDS)
15563         local target=$(do_nodes $mds 'lctl dl' |
15564                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15565
15566         local cmd1="file_count=1000 thrhi=4"
15567         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15568         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15569         local cmd="$cmd1 $cmd2 $cmd3"
15570
15571         rm -f ${TMP}/mds_survey*
15572         echo + $cmd
15573         eval $cmd || error "mds-survey with zero-stripe failed"
15574         cat ${TMP}/mds_survey*
15575         rm -f ${TMP}/mds_survey*
15576 }
15577 run_test 225a "Metadata survey sanity with zero-stripe"
15578
15579 test_225b () {
15580         if [ -z ${MDSSURVEY} ]; then
15581                 skip_env "mds-survey not found"
15582         fi
15583         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15584                 skip "Need MDS version at least 2.2.51"
15585         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15586         remote_mds_nodsh && skip "remote MDS with nodsh"
15587         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15588                 skip_env "Need to mount OST to test"
15589         fi
15590
15591         local mds=$(facet_host $SINGLEMDS)
15592         local target=$(do_nodes $mds 'lctl dl' |
15593                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15594
15595         local cmd1="file_count=1000 thrhi=4"
15596         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15597         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15598         local cmd="$cmd1 $cmd2 $cmd3"
15599
15600         rm -f ${TMP}/mds_survey*
15601         echo + $cmd
15602         eval $cmd || error "mds-survey with stripe_count failed"
15603         cat ${TMP}/mds_survey*
15604         rm -f ${TMP}/mds_survey*
15605 }
15606 run_test 225b "Metadata survey sanity with stripe_count = 1"
15607
15608 mcreate_path2fid () {
15609         local mode=$1
15610         local major=$2
15611         local minor=$3
15612         local name=$4
15613         local desc=$5
15614         local path=$DIR/$tdir/$name
15615         local fid
15616         local rc
15617         local fid_path
15618
15619         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15620                 error "cannot create $desc"
15621
15622         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15623         rc=$?
15624         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15625
15626         fid_path=$($LFS fid2path $MOUNT $fid)
15627         rc=$?
15628         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15629
15630         [ "$path" == "$fid_path" ] ||
15631                 error "fid2path returned $fid_path, expected $path"
15632
15633         echo "pass with $path and $fid"
15634 }
15635
15636 test_226a () {
15637         rm -rf $DIR/$tdir
15638         mkdir -p $DIR/$tdir
15639
15640         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15641         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15642         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15643         mcreate_path2fid 0040666 0 0 dir "directory"
15644         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15645         mcreate_path2fid 0100666 0 0 file "regular file"
15646         mcreate_path2fid 0120666 0 0 link "symbolic link"
15647         mcreate_path2fid 0140666 0 0 sock "socket"
15648 }
15649 run_test 226a "call path2fid and fid2path on files of all type"
15650
15651 test_226b () {
15652         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15653
15654         local MDTIDX=1
15655
15656         rm -rf $DIR/$tdir
15657         mkdir -p $DIR/$tdir
15658         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15659                 error "create remote directory failed"
15660         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15661         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15662                                 "character special file (null)"
15663         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15664                                 "character special file (no device)"
15665         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15666         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15667                                 "block special file (loop)"
15668         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15669         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15670         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15671 }
15672 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15673
15674 # LU-1299 Executing or running ldd on a truncated executable does not
15675 # cause an out-of-memory condition.
15676 test_227() {
15677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15678         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15679
15680         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15681         chmod +x $MOUNT/date
15682
15683         $MOUNT/date > /dev/null
15684         ldd $MOUNT/date > /dev/null
15685         rm -f $MOUNT/date
15686 }
15687 run_test 227 "running truncated executable does not cause OOM"
15688
15689 # LU-1512 try to reuse idle OI blocks
15690 test_228a() {
15691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15692         remote_mds_nodsh && skip "remote MDS with nodsh"
15693         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15694
15695         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15696         local myDIR=$DIR/$tdir
15697
15698         mkdir -p $myDIR
15699         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15700         $LCTL set_param fail_loc=0x80001002
15701         createmany -o $myDIR/t- 10000
15702         $LCTL set_param fail_loc=0
15703         # The guard is current the largest FID holder
15704         touch $myDIR/guard
15705         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15706                     tr -d '[')
15707         local IDX=$(($SEQ % 64))
15708
15709         do_facet $SINGLEMDS sync
15710         # Make sure journal flushed.
15711         sleep 6
15712         local blk1=$(do_facet $SINGLEMDS \
15713                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15714                      grep Blockcount | awk '{print $4}')
15715
15716         # Remove old files, some OI blocks will become idle.
15717         unlinkmany $myDIR/t- 10000
15718         # Create new files, idle OI blocks should be reused.
15719         createmany -o $myDIR/t- 2000
15720         do_facet $SINGLEMDS sync
15721         # Make sure journal flushed.
15722         sleep 6
15723         local blk2=$(do_facet $SINGLEMDS \
15724                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15725                      grep Blockcount | awk '{print $4}')
15726
15727         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15728 }
15729 run_test 228a "try to reuse idle OI blocks"
15730
15731 test_228b() {
15732         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15733         remote_mds_nodsh && skip "remote MDS with nodsh"
15734         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15735
15736         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15737         local myDIR=$DIR/$tdir
15738
15739         mkdir -p $myDIR
15740         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15741         $LCTL set_param fail_loc=0x80001002
15742         createmany -o $myDIR/t- 10000
15743         $LCTL set_param fail_loc=0
15744         # The guard is current the largest FID holder
15745         touch $myDIR/guard
15746         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15747                     tr -d '[')
15748         local IDX=$(($SEQ % 64))
15749
15750         do_facet $SINGLEMDS sync
15751         # Make sure journal flushed.
15752         sleep 6
15753         local blk1=$(do_facet $SINGLEMDS \
15754                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15755                      grep Blockcount | awk '{print $4}')
15756
15757         # Remove old files, some OI blocks will become idle.
15758         unlinkmany $myDIR/t- 10000
15759
15760         # stop the MDT
15761         stop $SINGLEMDS || error "Fail to stop MDT."
15762         # remount the MDT
15763         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
15764
15765         df $MOUNT || error "Fail to df."
15766         # Create new files, idle OI blocks should be reused.
15767         createmany -o $myDIR/t- 2000
15768         do_facet $SINGLEMDS sync
15769         # Make sure journal flushed.
15770         sleep 6
15771         local blk2=$(do_facet $SINGLEMDS \
15772                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15773                      grep Blockcount | awk '{print $4}')
15774
15775         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15776 }
15777 run_test 228b "idle OI blocks can be reused after MDT restart"
15778
15779 #LU-1881
15780 test_228c() {
15781         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15782         remote_mds_nodsh && skip "remote MDS with nodsh"
15783         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15784
15785         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15786         local myDIR=$DIR/$tdir
15787
15788         mkdir -p $myDIR
15789         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15790         $LCTL set_param fail_loc=0x80001002
15791         # 20000 files can guarantee there are index nodes in the OI file
15792         createmany -o $myDIR/t- 20000
15793         $LCTL set_param fail_loc=0
15794         # The guard is current the largest FID holder
15795         touch $myDIR/guard
15796         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15797                     tr -d '[')
15798         local IDX=$(($SEQ % 64))
15799
15800         do_facet $SINGLEMDS sync
15801         # Make sure journal flushed.
15802         sleep 6
15803         local blk1=$(do_facet $SINGLEMDS \
15804                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15805                      grep Blockcount | awk '{print $4}')
15806
15807         # Remove old files, some OI blocks will become idle.
15808         unlinkmany $myDIR/t- 20000
15809         rm -f $myDIR/guard
15810         # The OI file should become empty now
15811
15812         # Create new files, idle OI blocks should be reused.
15813         createmany -o $myDIR/t- 2000
15814         do_facet $SINGLEMDS sync
15815         # Make sure journal flushed.
15816         sleep 6
15817         local blk2=$(do_facet $SINGLEMDS \
15818                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15819                      grep Blockcount | awk '{print $4}')
15820
15821         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15822 }
15823 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
15824
15825 test_229() { # LU-2482, LU-3448
15826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15827         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
15828         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
15829                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
15830
15831         rm -f $DIR/$tfile
15832
15833         # Create a file with a released layout and stripe count 2.
15834         $MULTIOP $DIR/$tfile H2c ||
15835                 error "failed to create file with released layout"
15836
15837         $LFS getstripe -v $DIR/$tfile
15838
15839         local pattern=$($LFS getstripe -L $DIR/$tfile)
15840         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
15841
15842         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
15843                 error "getstripe"
15844         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
15845         stat $DIR/$tfile || error "failed to stat released file"
15846
15847         chown $RUNAS_ID $DIR/$tfile ||
15848                 error "chown $RUNAS_ID $DIR/$tfile failed"
15849
15850         chgrp $RUNAS_ID $DIR/$tfile ||
15851                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
15852
15853         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
15854         rm $DIR/$tfile || error "failed to remove released file"
15855 }
15856 run_test 229 "getstripe/stat/rm/attr changes work on released files"
15857
15858 test_230a() {
15859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15860         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15861         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15862                 skip "Need MDS version at least 2.11.52"
15863
15864         local MDTIDX=1
15865
15866         test_mkdir $DIR/$tdir
15867         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
15868         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
15869         [ $mdt_idx -ne 0 ] &&
15870                 error "create local directory on wrong MDT $mdt_idx"
15871
15872         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
15873                         error "create remote directory failed"
15874         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
15875         [ $mdt_idx -ne $MDTIDX ] &&
15876                 error "create remote directory on wrong MDT $mdt_idx"
15877
15878         createmany -o $DIR/$tdir/test_230/t- 10 ||
15879                 error "create files on remote directory failed"
15880         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
15881         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
15882         rm -r $DIR/$tdir || error "unlink remote directory failed"
15883 }
15884 run_test 230a "Create remote directory and files under the remote directory"
15885
15886 test_230b() {
15887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15888         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15889         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
15890                 skip "Need MDS version at least 2.11.52"
15891
15892         local MDTIDX=1
15893         local mdt_index
15894         local i
15895         local file
15896         local pid
15897         local stripe_count
15898         local migrate_dir=$DIR/$tdir/migrate_dir
15899         local other_dir=$DIR/$tdir/other_dir
15900
15901         test_mkdir $DIR/$tdir
15902         test_mkdir -i0 -c1 $migrate_dir
15903         test_mkdir -i0 -c1 $other_dir
15904         for ((i=0; i<10; i++)); do
15905                 mkdir -p $migrate_dir/dir_${i}
15906                 createmany -o $migrate_dir/dir_${i}/f 10 ||
15907                         error "create files under remote dir failed $i"
15908         done
15909
15910         cp /etc/passwd $migrate_dir/$tfile
15911         cp /etc/passwd $other_dir/$tfile
15912         chattr +SAD $migrate_dir
15913         chattr +SAD $migrate_dir/$tfile
15914
15915         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15916         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15917         local old_dir_mode=$(stat -c%f $migrate_dir)
15918         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
15919
15920         mkdir -p $migrate_dir/dir_default_stripe2
15921         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
15922         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
15923
15924         mkdir -p $other_dir
15925         ln $migrate_dir/$tfile $other_dir/luna
15926         ln $migrate_dir/$tfile $migrate_dir/sofia
15927         ln $other_dir/$tfile $migrate_dir/david
15928         ln -s $migrate_dir/$tfile $other_dir/zachary
15929         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
15930         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
15931
15932         $LFS migrate -m $MDTIDX $migrate_dir ||
15933                 error "fails on migrating remote dir to MDT1"
15934
15935         echo "migratate to MDT1, then checking.."
15936         for ((i = 0; i < 10; i++)); do
15937                 for file in $(find $migrate_dir/dir_${i}); do
15938                         mdt_index=$($LFS getstripe -m $file)
15939                         [ $mdt_index == $MDTIDX ] ||
15940                                 error "$file is not on MDT${MDTIDX}"
15941                 done
15942         done
15943
15944         # the multiple link file should still in MDT0
15945         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
15946         [ $mdt_index == 0 ] ||
15947                 error "$file is not on MDT${MDTIDX}"
15948
15949         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
15950         [ "$old_dir_flag" = "$new_dir_flag" ] ||
15951                 error " expect $old_dir_flag get $new_dir_flag"
15952
15953         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
15954         [ "$old_file_flag" = "$new_file_flag" ] ||
15955                 error " expect $old_file_flag get $new_file_flag"
15956
15957         local new_dir_mode=$(stat -c%f $migrate_dir)
15958         [ "$old_dir_mode" = "$new_dir_mode" ] ||
15959                 error "expect mode $old_dir_mode get $new_dir_mode"
15960
15961         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
15962         [ "$old_file_mode" = "$new_file_mode" ] ||
15963                 error "expect mode $old_file_mode get $new_file_mode"
15964
15965         diff /etc/passwd $migrate_dir/$tfile ||
15966                 error "$tfile different after migration"
15967
15968         diff /etc/passwd $other_dir/luna ||
15969                 error "luna different after migration"
15970
15971         diff /etc/passwd $migrate_dir/sofia ||
15972                 error "sofia different after migration"
15973
15974         diff /etc/passwd $migrate_dir/david ||
15975                 error "david different after migration"
15976
15977         diff /etc/passwd $other_dir/zachary ||
15978                 error "zachary different after migration"
15979
15980         diff /etc/passwd $migrate_dir/${tfile}_ln ||
15981                 error "${tfile}_ln different after migration"
15982
15983         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
15984                 error "${tfile}_ln_other different after migration"
15985
15986         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
15987         [ $stripe_count = 2 ] ||
15988                 error "dir strpe_count $d != 2 after migration."
15989
15990         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
15991         [ $stripe_count = 2 ] ||
15992                 error "file strpe_count $d != 2 after migration."
15993
15994         #migrate back to MDT0
15995         MDTIDX=0
15996
15997         $LFS migrate -m $MDTIDX $migrate_dir ||
15998                 error "fails on migrating remote dir to MDT0"
15999
16000         echo "migrate back to MDT0, checking.."
16001         for file in $(find $migrate_dir); do
16002                 mdt_index=$($LFS getstripe -m $file)
16003                 [ $mdt_index == $MDTIDX ] ||
16004                         error "$file is not on MDT${MDTIDX}"
16005         done
16006
16007         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16008         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16009                 error " expect $old_dir_flag get $new_dir_flag"
16010
16011         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16012         [ "$old_file_flag" = "$new_file_flag" ] ||
16013                 error " expect $old_file_flag get $new_file_flag"
16014
16015         local new_dir_mode=$(stat -c%f $migrate_dir)
16016         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16017                 error "expect mode $old_dir_mode get $new_dir_mode"
16018
16019         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16020         [ "$old_file_mode" = "$new_file_mode" ] ||
16021                 error "expect mode $old_file_mode get $new_file_mode"
16022
16023         diff /etc/passwd ${migrate_dir}/$tfile ||
16024                 error "$tfile different after migration"
16025
16026         diff /etc/passwd ${other_dir}/luna ||
16027                 error "luna different after migration"
16028
16029         diff /etc/passwd ${migrate_dir}/sofia ||
16030                 error "sofia different after migration"
16031
16032         diff /etc/passwd ${other_dir}/zachary ||
16033                 error "zachary different after migration"
16034
16035         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16036                 error "${tfile}_ln different after migration"
16037
16038         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16039                 error "${tfile}_ln_other different after migration"
16040
16041         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16042         [ $stripe_count = 2 ] ||
16043                 error "dir strpe_count $d != 2 after migration."
16044
16045         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16046         [ $stripe_count = 2 ] ||
16047                 error "file strpe_count $d != 2 after migration."
16048
16049         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16050 }
16051 run_test 230b "migrate directory"
16052
16053 test_230c() {
16054         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16055         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16056         remote_mds_nodsh && skip "remote MDS with nodsh"
16057         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16058                 skip "Need MDS version at least 2.11.52"
16059
16060         local MDTIDX=1
16061         local total=3
16062         local mdt_index
16063         local file
16064         local migrate_dir=$DIR/$tdir/migrate_dir
16065
16066         #If migrating directory fails in the middle, all entries of
16067         #the directory is still accessiable.
16068         test_mkdir $DIR/$tdir
16069         test_mkdir -i0 -c1 $migrate_dir
16070         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16071         stat $migrate_dir
16072         createmany -o $migrate_dir/f $total ||
16073                 error "create files under ${migrate_dir} failed"
16074
16075         # fail after migrating top dir, and this will fail only once, so the
16076         # first sub file migration will fail (currently f3), others succeed.
16077         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16078         do_facet mds1 lctl set_param fail_loc=0x1801
16079         local t=$(ls $migrate_dir | wc -l)
16080         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16081                 error "migrate should fail"
16082         local u=$(ls $migrate_dir | wc -l)
16083         [ "$u" == "$t" ] || error "$u != $t during migration"
16084
16085         # add new dir/file should succeed
16086         mkdir $migrate_dir/dir ||
16087                 error "mkdir failed under migrating directory"
16088         touch $migrate_dir/file ||
16089                 error "create file failed under migrating directory"
16090
16091         # add file with existing name should fail
16092         for file in $migrate_dir/f*; do
16093                 stat $file > /dev/null || error "stat $file failed"
16094                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16095                         error "open(O_CREAT|O_EXCL) $file should fail"
16096                 $MULTIOP $file m && error "create $file should fail"
16097                 touch $DIR/$tdir/remote_dir/$tfile ||
16098                         error "touch $tfile failed"
16099                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16100                         error "link $file should fail"
16101                 mdt_index=$($LFS getstripe -m $file)
16102                 if [ $mdt_index == 0 ]; then
16103                         # file failed to migrate is not allowed to rename to
16104                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16105                                 error "rename to $file should fail"
16106                 else
16107                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16108                                 error "rename to $file failed"
16109                 fi
16110                 echo hello >> $file || error "write $file failed"
16111         done
16112
16113         # resume migration with different options should fail
16114         $LFS migrate -m 0 $migrate_dir &&
16115                 error "migrate -m 0 $migrate_dir should fail"
16116
16117         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16118                 error "migrate -c 2 $migrate_dir should fail"
16119
16120         # resume migration should succeed
16121         $LFS migrate -m $MDTIDX $migrate_dir ||
16122                 error "migrate $migrate_dir failed"
16123
16124         echo "Finish migration, then checking.."
16125         for file in $(find $migrate_dir); do
16126                 mdt_index=$($LFS getstripe -m $file)
16127                 [ $mdt_index == $MDTIDX ] ||
16128                         error "$file is not on MDT${MDTIDX}"
16129         done
16130
16131         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16132 }
16133 run_test 230c "check directory accessiblity if migration failed"
16134
16135 test_230d() {
16136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16137         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16138         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16139                 skip "Need MDS version at least 2.11.52"
16140         # LU-11235
16141         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16142
16143         local migrate_dir=$DIR/$tdir/migrate_dir
16144         local old_index
16145         local new_index
16146         local old_count
16147         local new_count
16148         local new_hash
16149         local mdt_index
16150         local i
16151         local j
16152
16153         old_index=$((RANDOM % MDSCOUNT))
16154         old_count=$((MDSCOUNT - old_index))
16155         new_index=$((RANDOM % MDSCOUNT))
16156         new_count=$((MDSCOUNT - new_index))
16157         new_hash="all_char"
16158
16159         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16160         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16161
16162         test_mkdir $DIR/$tdir
16163         test_mkdir -i $old_index -c $old_count $migrate_dir
16164
16165         for ((i=0; i<100; i++)); do
16166                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16167                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16168                         error "create files under remote dir failed $i"
16169         done
16170
16171         echo -n "Migrate from MDT$old_index "
16172         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16173         echo -n "to MDT$new_index"
16174         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16175         echo
16176
16177         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16178         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16179                 error "migrate remote dir error"
16180
16181         echo "Finish migration, then checking.."
16182         for file in $(find $migrate_dir); do
16183                 mdt_index=$($LFS getstripe -m $file)
16184                 if [ $mdt_index -lt $new_index ] ||
16185                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16186                         error "$file is on MDT$mdt_index"
16187                 fi
16188         done
16189
16190         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16191 }
16192 run_test 230d "check migrate big directory"
16193
16194 test_230e() {
16195         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16196         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16197         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16198                 skip "Need MDS version at least 2.11.52"
16199
16200         local i
16201         local j
16202         local a_fid
16203         local b_fid
16204
16205         mkdir -p $DIR/$tdir
16206         mkdir $DIR/$tdir/migrate_dir
16207         mkdir $DIR/$tdir/other_dir
16208         touch $DIR/$tdir/migrate_dir/a
16209         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16210         ls $DIR/$tdir/other_dir
16211
16212         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16213                 error "migrate dir fails"
16214
16215         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16216         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16217
16218         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16219         [ $mdt_index == 0 ] || error "a is not on MDT0"
16220
16221         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16222                 error "migrate dir fails"
16223
16224         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16225         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16226
16227         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16228         [ $mdt_index == 1 ] || error "a is not on MDT1"
16229
16230         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16231         [ $mdt_index == 1 ] || error "b is not on MDT1"
16232
16233         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16234         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16235
16236         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16237
16238         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16239 }
16240 run_test 230e "migrate mulitple local link files"
16241
16242 test_230f() {
16243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16244         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16245         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16246                 skip "Need MDS version at least 2.11.52"
16247
16248         local a_fid
16249         local ln_fid
16250
16251         mkdir -p $DIR/$tdir
16252         mkdir $DIR/$tdir/migrate_dir
16253         $LFS mkdir -i1 $DIR/$tdir/other_dir
16254         touch $DIR/$tdir/migrate_dir/a
16255         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16256         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16257         ls $DIR/$tdir/other_dir
16258
16259         # a should be migrated to MDT1, since no other links on MDT0
16260         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16261                 error "#1 migrate dir fails"
16262         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16263         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16264         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16265         [ $mdt_index == 1 ] || error "a is not on MDT1"
16266
16267         # a should stay on MDT1, because it is a mulitple link file
16268         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16269                 error "#2 migrate dir fails"
16270         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16271         [ $mdt_index == 1 ] || error "a is not on MDT1"
16272
16273         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16274                 error "#3 migrate dir fails"
16275
16276         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16277         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16278         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16279
16280         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16281         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16282
16283         # a should be migrated to MDT0, since no other links on MDT1
16284         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16285                 error "#4 migrate dir fails"
16286         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16287         [ $mdt_index == 0 ] || error "a is not on MDT0"
16288
16289         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16290 }
16291 run_test 230f "migrate mulitple remote link files"
16292
16293 test_230g() {
16294         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16295         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16296         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16297                 skip "Need MDS version at least 2.11.52"
16298
16299         mkdir -p $DIR/$tdir/migrate_dir
16300
16301         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16302                 error "migrating dir to non-exist MDT succeeds"
16303         true
16304 }
16305 run_test 230g "migrate dir to non-exist MDT"
16306
16307 test_230h() {
16308         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16309         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16310         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16311                 skip "Need MDS version at least 2.11.52"
16312
16313         local mdt_index
16314
16315         mkdir -p $DIR/$tdir/migrate_dir
16316
16317         $LFS migrate -m1 $DIR &&
16318                 error "migrating mountpoint1 should fail"
16319
16320         $LFS migrate -m1 $DIR/$tdir/.. &&
16321                 error "migrating mountpoint2 should fail"
16322
16323         # same as mv
16324         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16325                 error "migrating $tdir/migrate_dir/.. should fail"
16326
16327         true
16328 }
16329 run_test 230h "migrate .. and root"
16330
16331 test_230i() {
16332         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16333         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16334         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16335                 skip "Need MDS version at least 2.11.52"
16336
16337         mkdir -p $DIR/$tdir/migrate_dir
16338
16339         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16340                 error "migration fails with a tailing slash"
16341
16342         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16343                 error "migration fails with two tailing slashes"
16344 }
16345 run_test 230i "lfs migrate -m tolerates trailing slashes"
16346
16347 test_230j() {
16348         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16349         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16350                 skip "Need MDS version at least 2.11.52"
16351
16352         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16353         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16354                 error "create $tfile failed"
16355         cat /etc/passwd > $DIR/$tdir/$tfile
16356
16357         $LFS migrate -m 1 $DIR/$tdir
16358
16359         cmp /etc/passwd $DIR/$tdir/$tfile ||
16360                 error "DoM file mismatch after migration"
16361 }
16362 run_test 230j "DoM file data not changed after dir migration"
16363
16364 test_230k() {
16365         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16366         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16367                 skip "Need MDS version at least 2.11.56"
16368
16369         local total=20
16370         local files_on_starting_mdt=0
16371
16372         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16373         $LFS getdirstripe $DIR/$tdir
16374         for i in $(seq $total); do
16375                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16376                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16377                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16378         done
16379
16380         echo "$files_on_starting_mdt files on MDT0"
16381
16382         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16383         $LFS getdirstripe $DIR/$tdir
16384
16385         files_on_starting_mdt=0
16386         for i in $(seq $total); do
16387                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16388                         error "file $tfile.$i mismatch after migration"
16389                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16390                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16391         done
16392
16393         echo "$files_on_starting_mdt files on MDT1 after migration"
16394         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16395
16396         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16397         $LFS getdirstripe $DIR/$tdir
16398
16399         files_on_starting_mdt=0
16400         for i in $(seq $total); do
16401                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16402                         error "file $tfile.$i mismatch after 2nd migration"
16403                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16404                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16405         done
16406
16407         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16408         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16409
16410         true
16411 }
16412 run_test 230k "file data not changed after dir migration"
16413
16414 test_230l() {
16415         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16416         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16417                 skip "Need MDS version at least 2.11.56"
16418
16419         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16420         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16421                 error "create files under remote dir failed $i"
16422         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16423 }
16424 run_test 230l "readdir between MDTs won't crash"
16425
16426 test_231a()
16427 {
16428         # For simplicity this test assumes that max_pages_per_rpc
16429         # is the same across all OSCs
16430         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16431         local bulk_size=$((max_pages * PAGE_SIZE))
16432         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16433                                        head -n 1)
16434
16435         mkdir -p $DIR/$tdir
16436         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16437                 error "failed to set stripe with -S ${brw_size}M option"
16438
16439         # clear the OSC stats
16440         $LCTL set_param osc.*.stats=0 &>/dev/null
16441         stop_writeback
16442
16443         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16444         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16445                 oflag=direct &>/dev/null || error "dd failed"
16446
16447         sync; sleep 1; sync # just to be safe
16448         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16449         if [ x$nrpcs != "x1" ]; then
16450                 $LCTL get_param osc.*.stats
16451                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16452         fi
16453
16454         start_writeback
16455         # Drop the OSC cache, otherwise we will read from it
16456         cancel_lru_locks osc
16457
16458         # clear the OSC stats
16459         $LCTL set_param osc.*.stats=0 &>/dev/null
16460
16461         # Client reads $bulk_size.
16462         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16463                 iflag=direct &>/dev/null || error "dd failed"
16464
16465         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16466         if [ x$nrpcs != "x1" ]; then
16467                 $LCTL get_param osc.*.stats
16468                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16469         fi
16470 }
16471 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16472
16473 test_231b() {
16474         mkdir -p $DIR/$tdir
16475         local i
16476         for i in {0..1023}; do
16477                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16478                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16479                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16480         done
16481         sync
16482 }
16483 run_test 231b "must not assert on fully utilized OST request buffer"
16484
16485 test_232a() {
16486         mkdir -p $DIR/$tdir
16487         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16488
16489         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16490         do_facet ost1 $LCTL set_param fail_loc=0x31c
16491
16492         # ignore dd failure
16493         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16494
16495         do_facet ost1 $LCTL set_param fail_loc=0
16496         umount_client $MOUNT || error "umount failed"
16497         mount_client $MOUNT || error "mount failed"
16498         stop ost1 || error "cannot stop ost1"
16499         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16500 }
16501 run_test 232a "failed lock should not block umount"
16502
16503 test_232b() {
16504         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16505                 skip "Need MDS version at least 2.10.58"
16506
16507         mkdir -p $DIR/$tdir
16508         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16509         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16510         sync
16511         cancel_lru_locks osc
16512
16513         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16514         do_facet ost1 $LCTL set_param fail_loc=0x31c
16515
16516         # ignore failure
16517         $LFS data_version $DIR/$tdir/$tfile || true
16518
16519         do_facet ost1 $LCTL set_param fail_loc=0
16520         umount_client $MOUNT || error "umount failed"
16521         mount_client $MOUNT || error "mount failed"
16522         stop ost1 || error "cannot stop ost1"
16523         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16524 }
16525 run_test 232b "failed data version lock should not block umount"
16526
16527 test_233a() {
16528         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16529                 skip "Need MDS version at least 2.3.64"
16530         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16531
16532         local fid=$($LFS path2fid $MOUNT)
16533
16534         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16535                 error "cannot access $MOUNT using its FID '$fid'"
16536 }
16537 run_test 233a "checking that OBF of the FS root succeeds"
16538
16539 test_233b() {
16540         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16541                 skip "Need MDS version at least 2.5.90"
16542         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16543
16544         local fid=$($LFS path2fid $MOUNT/.lustre)
16545
16546         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16547                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16548
16549         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16550         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16551                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16552 }
16553 run_test 233b "checking that OBF of the FS .lustre succeeds"
16554
16555 test_234() {
16556         local p="$TMP/sanityN-$TESTNAME.parameters"
16557         save_lustre_params client "llite.*.xattr_cache" > $p
16558         lctl set_param llite.*.xattr_cache 1 ||
16559                 skip_env "xattr cache is not supported"
16560
16561         mkdir -p $DIR/$tdir || error "mkdir failed"
16562         touch $DIR/$tdir/$tfile || error "touch failed"
16563         # OBD_FAIL_LLITE_XATTR_ENOMEM
16564         $LCTL set_param fail_loc=0x1405
16565         getfattr -n user.attr $DIR/$tdir/$tfile &&
16566                 error "getfattr should have failed with ENOMEM"
16567         $LCTL set_param fail_loc=0x0
16568         rm -rf $DIR/$tdir
16569
16570         restore_lustre_params < $p
16571         rm -f $p
16572 }
16573 run_test 234 "xattr cache should not crash on ENOMEM"
16574
16575 test_235() {
16576         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16577                 skip "Need MDS version at least 2.4.52"
16578
16579         flock_deadlock $DIR/$tfile
16580         local RC=$?
16581         case $RC in
16582                 0)
16583                 ;;
16584                 124) error "process hangs on a deadlock"
16585                 ;;
16586                 *) error "error executing flock_deadlock $DIR/$tfile"
16587                 ;;
16588         esac
16589 }
16590 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16591
16592 #LU-2935
16593 test_236() {
16594         check_swap_layouts_support
16595
16596         local ref1=/etc/passwd
16597         local ref2=/etc/group
16598         local file1=$DIR/$tdir/f1
16599         local file2=$DIR/$tdir/f2
16600
16601         test_mkdir -c1 $DIR/$tdir
16602         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16603         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16604         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16605         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16606         local fd=$(free_fd)
16607         local cmd="exec $fd<>$file2"
16608         eval $cmd
16609         rm $file2
16610         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16611                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16612         cmd="exec $fd>&-"
16613         eval $cmd
16614         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16615
16616         #cleanup
16617         rm -rf $DIR/$tdir
16618 }
16619 run_test 236 "Layout swap on open unlinked file"
16620
16621 # LU-4659 linkea consistency
16622 test_238() {
16623         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16624                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16625                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16626                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16627
16628         touch $DIR/$tfile
16629         ln $DIR/$tfile $DIR/$tfile.lnk
16630         touch $DIR/$tfile.new
16631         mv $DIR/$tfile.new $DIR/$tfile
16632         local fid1=$($LFS path2fid $DIR/$tfile)
16633         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16634         local path1=$($LFS fid2path $FSNAME "$fid1")
16635         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16636         local path2=$($LFS fid2path $FSNAME "$fid2")
16637         [ $tfile.lnk == $path2 ] ||
16638                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16639         rm -f $DIR/$tfile*
16640 }
16641 run_test 238 "Verify linkea consistency"
16642
16643 test_239A() { # was test_239
16644         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16645                 skip "Need MDS version at least 2.5.60"
16646
16647         local list=$(comma_list $(mdts_nodes))
16648
16649         mkdir -p $DIR/$tdir
16650         createmany -o $DIR/$tdir/f- 5000
16651         unlinkmany $DIR/$tdir/f- 5000
16652         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16653                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16654         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16655                         osp.*MDT*.sync_in_flight" | calc_sum)
16656         [ "$changes" -eq 0 ] || error "$changes not synced"
16657 }
16658 run_test 239A "osp_sync test"
16659
16660 test_239a() { #LU-5297
16661         remote_mds_nodsh && skip "remote MDS with nodsh"
16662
16663         touch $DIR/$tfile
16664         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16665         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16666         chgrp $RUNAS_GID $DIR/$tfile
16667         wait_delete_completed
16668 }
16669 run_test 239a "process invalid osp sync record correctly"
16670
16671 test_239b() { #LU-5297
16672         remote_mds_nodsh && skip "remote MDS with nodsh"
16673
16674         touch $DIR/$tfile1
16675         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16676         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16677         chgrp $RUNAS_GID $DIR/$tfile1
16678         wait_delete_completed
16679         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16680         touch $DIR/$tfile2
16681         chgrp $RUNAS_GID $DIR/$tfile2
16682         wait_delete_completed
16683 }
16684 run_test 239b "process osp sync record with ENOMEM error correctly"
16685
16686 test_240() {
16687         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16688         remote_mds_nodsh && skip "remote MDS with nodsh"
16689
16690         mkdir -p $DIR/$tdir
16691
16692         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16693                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16694         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16695                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16696
16697         umount_client $MOUNT || error "umount failed"
16698         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16699         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16700         mount_client $MOUNT || error "failed to mount client"
16701
16702         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16703         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16704 }
16705 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16706
16707 test_241_bio() {
16708         local count=$1
16709         local bsize=$2
16710
16711         for LOOP in $(seq $count); do
16712                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16713                 cancel_lru_locks $OSC || true
16714         done
16715 }
16716
16717 test_241_dio() {
16718         local count=$1
16719         local bsize=$2
16720
16721         for LOOP in $(seq $1); do
16722                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16723                         2>/dev/null
16724         done
16725 }
16726
16727 test_241a() { # was test_241
16728         local bsize=$PAGE_SIZE
16729
16730         (( bsize < 40960 )) && bsize=40960
16731         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16732         ls -la $DIR/$tfile
16733         cancel_lru_locks $OSC
16734         test_241_bio 1000 $bsize &
16735         PID=$!
16736         test_241_dio 1000 $bsize
16737         wait $PID
16738 }
16739 run_test 241a "bio vs dio"
16740
16741 test_241b() {
16742         local bsize=$PAGE_SIZE
16743
16744         (( bsize < 40960 )) && bsize=40960
16745         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16746         ls -la $DIR/$tfile
16747         test_241_dio 1000 $bsize &
16748         PID=$!
16749         test_241_dio 1000 $bsize
16750         wait $PID
16751 }
16752 run_test 241b "dio vs dio"
16753
16754 test_242() {
16755         remote_mds_nodsh && skip "remote MDS with nodsh"
16756
16757         mkdir -p $DIR/$tdir
16758         touch $DIR/$tdir/$tfile
16759
16760         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
16761         do_facet mds1 lctl set_param fail_loc=0x105
16762         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
16763
16764         do_facet mds1 lctl set_param fail_loc=0
16765         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
16766 }
16767 run_test 242 "mdt_readpage failure should not cause directory unreadable"
16768
16769 test_243()
16770 {
16771         test_mkdir $DIR/$tdir
16772         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
16773 }
16774 run_test 243 "various group lock tests"
16775
16776 test_244()
16777 {
16778         test_mkdir $DIR/$tdir
16779         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
16780         sendfile_grouplock $DIR/$tdir/$tfile || \
16781                 error "sendfile+grouplock failed"
16782         rm -rf $DIR/$tdir
16783 }
16784 run_test 244 "sendfile with group lock tests"
16785
16786 test_245() {
16787         local flagname="multi_mod_rpcs"
16788         local connect_data_name="max_mod_rpcs"
16789         local out
16790
16791         # check if multiple modify RPCs flag is set
16792         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
16793                 grep "connect_flags:")
16794         echo "$out"
16795
16796         echo "$out" | grep -qw $flagname
16797         if [ $? -ne 0 ]; then
16798                 echo "connect flag $flagname is not set"
16799                 return
16800         fi
16801
16802         # check if multiple modify RPCs data is set
16803         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
16804         echo "$out"
16805
16806         echo "$out" | grep -qw $connect_data_name ||
16807                 error "import should have connect data $connect_data_name"
16808 }
16809 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
16810
16811 test_246() { # LU-7371
16812         remote_ost_nodsh && skip "remote OST with nodsh"
16813         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
16814                 skip "Need OST version >= 2.7.62"
16815
16816         do_facet ost1 $LCTL set_param fail_val=4095
16817 #define OBD_FAIL_OST_READ_SIZE          0x234
16818         do_facet ost1 $LCTL set_param fail_loc=0x234
16819         $LFS setstripe $DIR/$tfile -i 0 -c 1
16820         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
16821         cancel_lru_locks $FSNAME-OST0000
16822         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
16823 }
16824 run_test 246 "Read file of size 4095 should return right length"
16825
16826 cleanup_247() {
16827         local submount=$1
16828
16829         trap 0
16830         umount_client $submount
16831         rmdir $submount
16832 }
16833
16834 test_247a() {
16835         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16836                 grep -q subtree ||
16837                 skip_env "Fileset feature is not supported"
16838
16839         local submount=${MOUNT}_$tdir
16840
16841         mkdir $MOUNT/$tdir
16842         mkdir -p $submount || error "mkdir $submount failed"
16843         FILESET="$FILESET/$tdir" mount_client $submount ||
16844                 error "mount $submount failed"
16845         trap "cleanup_247 $submount" EXIT
16846         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
16847         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
16848                 error "read $MOUNT/$tdir/$tfile failed"
16849         cleanup_247 $submount
16850 }
16851 run_test 247a "mount subdir as fileset"
16852
16853 test_247b() {
16854         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16855                 skip_env "Fileset feature is not supported"
16856
16857         local submount=${MOUNT}_$tdir
16858
16859         rm -rf $MOUNT/$tdir
16860         mkdir -p $submount || error "mkdir $submount failed"
16861         SKIP_FILESET=1
16862         FILESET="$FILESET/$tdir" mount_client $submount &&
16863                 error "mount $submount should fail"
16864         rmdir $submount
16865 }
16866 run_test 247b "mount subdir that dose not exist"
16867
16868 test_247c() {
16869         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16870                 skip_env "Fileset feature is not supported"
16871
16872         local submount=${MOUNT}_$tdir
16873
16874         mkdir -p $MOUNT/$tdir/dir1
16875         mkdir -p $submount || error "mkdir $submount failed"
16876         trap "cleanup_247 $submount" EXIT
16877         FILESET="$FILESET/$tdir" mount_client $submount ||
16878                 error "mount $submount failed"
16879         local fid=$($LFS path2fid $MOUNT/)
16880         $LFS fid2path $submount $fid && error "fid2path should fail"
16881         cleanup_247 $submount
16882 }
16883 run_test 247c "running fid2path outside root"
16884
16885 test_247d() {
16886         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
16887                 skip "Fileset feature is not supported"
16888
16889         local submount=${MOUNT}_$tdir
16890
16891         mkdir -p $MOUNT/$tdir/dir1
16892         mkdir -p $submount || error "mkdir $submount failed"
16893         FILESET="$FILESET/$tdir" mount_client $submount ||
16894                 error "mount $submount failed"
16895         trap "cleanup_247 $submount" EXIT
16896         local fid=$($LFS path2fid $submount/dir1)
16897         $LFS fid2path $submount $fid || error "fid2path should succeed"
16898         cleanup_247 $submount
16899 }
16900 run_test 247d "running fid2path inside root"
16901
16902 # LU-8037
16903 test_247e() {
16904         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
16905                 grep -q subtree ||
16906                 skip "Fileset feature is not supported"
16907
16908         local submount=${MOUNT}_$tdir
16909
16910         mkdir $MOUNT/$tdir
16911         mkdir -p $submount || error "mkdir $submount failed"
16912         FILESET="$FILESET/.." mount_client $submount &&
16913                 error "mount $submount should fail"
16914         rmdir $submount
16915 }
16916 run_test 247e "mount .. as fileset"
16917
16918 test_248() {
16919         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
16920         [ -z "$fast_read_sav" ] && skip "no fast read support"
16921
16922         # create a large file for fast read verification
16923         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
16924
16925         # make sure the file is created correctly
16926         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
16927                 { rm -f $DIR/$tfile; skip "file creation error"; }
16928
16929         echo "Test 1: verify that fast read is 4 times faster on cache read"
16930
16931         # small read with fast read enabled
16932         $LCTL set_param -n llite.*.fast_read=1
16933         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16934                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16935                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16936         # small read with fast read disabled
16937         $LCTL set_param -n llite.*.fast_read=0
16938         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
16939                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16940                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16941
16942         # verify that fast read is 4 times faster for cache read
16943         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
16944                 error_not_in_vm "fast read was not 4 times faster: " \
16945                            "$t_fast vs $t_slow"
16946
16947         echo "Test 2: verify the performance between big and small read"
16948         $LCTL set_param -n llite.*.fast_read=1
16949
16950         # 1k non-cache read
16951         cancel_lru_locks osc
16952         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16953                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16954                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16955
16956         # 1M non-cache read
16957         cancel_lru_locks osc
16958         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
16959                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
16960                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
16961
16962         # verify that big IO is not 4 times faster than small IO
16963         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
16964                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
16965
16966         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
16967         rm -f $DIR/$tfile
16968 }
16969 run_test 248 "fast read verification"
16970
16971 test_249() { # LU-7890
16972         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
16973                 skip "Need at least version 2.8.54"
16974
16975         rm -f $DIR/$tfile
16976         $LFS setstripe -c 1 $DIR/$tfile
16977         # Offset 2T == 4k * 512M
16978         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
16979                 error "dd to 2T offset failed"
16980 }
16981 run_test 249 "Write above 2T file size"
16982
16983 test_250() {
16984         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
16985          && skip "no 16TB file size limit on ZFS"
16986
16987         $LFS setstripe -c 1 $DIR/$tfile
16988         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
16989         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
16990         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
16991         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
16992                 conv=notrunc,fsync && error "append succeeded"
16993         return 0
16994 }
16995 run_test 250 "Write above 16T limit"
16996
16997 test_251() {
16998         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
16999
17000         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17001         #Skip once - writing the first stripe will succeed
17002         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17003         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17004                 error "short write happened"
17005
17006         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17007         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17008                 error "short read happened"
17009
17010         rm -f $DIR/$tfile
17011 }
17012 run_test 251 "Handling short read and write correctly"
17013
17014 test_252() {
17015         remote_mds_nodsh && skip "remote MDS with nodsh"
17016         remote_ost_nodsh && skip "remote OST with nodsh"
17017         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17018                 skip_env "ldiskfs only test"
17019         fi
17020
17021         local tgt
17022         local dev
17023         local out
17024         local uuid
17025         local num
17026         local gen
17027
17028         # check lr_reader on OST0000
17029         tgt=ost1
17030         dev=$(facet_device $tgt)
17031         out=$(do_facet $tgt $LR_READER $dev)
17032         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17033         echo "$out"
17034         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17035         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17036                 error "Invalid uuid returned by $LR_READER on target $tgt"
17037         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17038
17039         # check lr_reader -c on MDT0000
17040         tgt=mds1
17041         dev=$(facet_device $tgt)
17042         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17043                 skip "$LR_READER does not support additional options"
17044         fi
17045         out=$(do_facet $tgt $LR_READER -c $dev)
17046         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17047         echo "$out"
17048         num=$(echo "$out" | grep -c "mdtlov")
17049         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17050                 error "Invalid number of mdtlov clients returned by $LR_READER"
17051         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17052
17053         # check lr_reader -cr on MDT0000
17054         out=$(do_facet $tgt $LR_READER -cr $dev)
17055         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17056         echo "$out"
17057         echo "$out" | grep -q "^reply_data:$" ||
17058                 error "$LR_READER should have returned 'reply_data' section"
17059         num=$(echo "$out" | grep -c "client_generation")
17060         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17061 }
17062 run_test 252 "check lr_reader tool"
17063
17064 test_253() {
17065         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17066         remote_mds_nodsh && skip "remote MDS with nodsh"
17067         remote_mgs_nodsh && skip "remote MGS with nodsh"
17068
17069         local ostidx=0
17070         local rc=0
17071         local ost_name=$(ostname_from_index $ostidx)
17072
17073         # on the mdt's osc
17074         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17075         do_facet $SINGLEMDS $LCTL get_param -n \
17076                 osp.$mdtosc_proc1.reserved_mb_high ||
17077                 skip  "remote MDS does not support reserved_mb_high"
17078
17079         rm -rf $DIR/$tdir
17080         wait_mds_ost_sync
17081         wait_delete_completed
17082         mkdir $DIR/$tdir
17083
17084         if ! combined_mgs_mds ; then
17085                 mount_mgs_client
17086         fi
17087         pool_add $TESTNAME || error "Pool creation failed"
17088         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17089
17090         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17091                 error "Setstripe failed"
17092
17093         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17094
17095         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17096                     grep "watermarks")
17097         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17098
17099         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17100                         osp.$mdtosc_proc1.prealloc_status)
17101         echo "prealloc_status $oa_status"
17102
17103         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17104                 error "File creation should fail"
17105
17106         #object allocation was stopped, but we still able to append files
17107         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17108                 oflag=append || error "Append failed"
17109
17110         rm -f $DIR/$tdir/$tfile.0
17111
17112         # For this test, we want to delete the files we created to go out of
17113         # space but leave the watermark, so we remain nearly out of space
17114         ost_watermarks_enospc_delete_files $tfile $ostidx
17115
17116         wait_delete_completed
17117
17118         sleep_maxage
17119
17120         for i in $(seq 10 12); do
17121                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17122                         2>/dev/null || error "File creation failed after rm"
17123         done
17124
17125         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17126                         osp.$mdtosc_proc1.prealloc_status)
17127         echo "prealloc_status $oa_status"
17128
17129         if (( oa_status != 0 )); then
17130                 error "Object allocation still disable after rm"
17131         fi
17132
17133         if ! combined_mgs_mds ; then
17134                 umount_mgs_client
17135         fi
17136 }
17137 run_test 253 "Check object allocation limit"
17138
17139 test_254() {
17140         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17141         remote_mds_nodsh && skip "remote MDS with nodsh"
17142         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17143                 skip "MDS does not support changelog_size"
17144
17145         local cl_user
17146         local MDT0=$(facet_svc $SINGLEMDS)
17147
17148         changelog_register || error "changelog_register failed"
17149
17150         changelog_clear 0 || error "changelog_clear failed"
17151
17152         local size1=$(do_facet $SINGLEMDS \
17153                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17154         echo "Changelog size $size1"
17155
17156         rm -rf $DIR/$tdir
17157         $LFS mkdir -i 0 $DIR/$tdir
17158         # change something
17159         mkdir -p $DIR/$tdir/pics/2008/zachy
17160         touch $DIR/$tdir/pics/2008/zachy/timestamp
17161         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17162         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17163         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17164         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17165         rm $DIR/$tdir/pics/desktop.jpg
17166
17167         local size2=$(do_facet $SINGLEMDS \
17168                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17169         echo "Changelog size after work $size2"
17170
17171         (( $size2 > $size1 )) ||
17172                 error "new Changelog size=$size2 less than old size=$size1"
17173 }
17174 run_test 254 "Check changelog size"
17175
17176 ladvise_no_type()
17177 {
17178         local type=$1
17179         local file=$2
17180
17181         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17182                 awk -F: '{print $2}' | grep $type > /dev/null
17183         if [ $? -ne 0 ]; then
17184                 return 0
17185         fi
17186         return 1
17187 }
17188
17189 ladvise_no_ioctl()
17190 {
17191         local file=$1
17192
17193         lfs ladvise -a willread $file > /dev/null 2>&1
17194         if [ $? -eq 0 ]; then
17195                 return 1
17196         fi
17197
17198         lfs ladvise -a willread $file 2>&1 |
17199                 grep "Inappropriate ioctl for device" > /dev/null
17200         if [ $? -eq 0 ]; then
17201                 return 0
17202         fi
17203         return 1
17204 }
17205
17206 percent() {
17207         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17208 }
17209
17210 # run a random read IO workload
17211 # usage: random_read_iops <filename> <filesize> <iosize>
17212 random_read_iops() {
17213         local file=$1
17214         local fsize=$2
17215         local iosize=${3:-4096}
17216
17217         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17218                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17219 }
17220
17221 drop_file_oss_cache() {
17222         local file="$1"
17223         local nodes="$2"
17224
17225         $LFS ladvise -a dontneed $file 2>/dev/null ||
17226                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17227 }
17228
17229 ladvise_willread_performance()
17230 {
17231         local repeat=10
17232         local average_origin=0
17233         local average_cache=0
17234         local average_ladvise=0
17235
17236         for ((i = 1; i <= $repeat; i++)); do
17237                 echo "Iter $i/$repeat: reading without willread hint"
17238                 cancel_lru_locks osc
17239                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17240                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17241                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17242                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17243
17244                 cancel_lru_locks osc
17245                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17246                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17247                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17248
17249                 cancel_lru_locks osc
17250                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17251                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17252                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17253                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17254                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17255         done
17256         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17257         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17258         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17259
17260         speedup_cache=$(percent $average_cache $average_origin)
17261         speedup_ladvise=$(percent $average_ladvise $average_origin)
17262
17263         echo "Average uncached read: $average_origin"
17264         echo "Average speedup with OSS cached read: " \
17265                 "$average_cache = +$speedup_cache%"
17266         echo "Average speedup with ladvise willread: " \
17267                 "$average_ladvise = +$speedup_ladvise%"
17268
17269         local lowest_speedup=20
17270         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17271                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17272                         "got $average_cache%. Skipping ladvise willread check."
17273                 return 0
17274         fi
17275
17276         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17277         # it is still good to run until then to exercise 'ladvise willread'
17278         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17279                 [ "$ost1_FSTYPE" = "zfs" ] &&
17280                 echo "osd-zfs does not support dontneed or drop_caches" &&
17281                 return 0
17282
17283         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17284         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17285                 error_not_in_vm "Speedup with willread is less than " \
17286                         "$lowest_speedup%, got $average_ladvise%"
17287 }
17288
17289 test_255a() {
17290         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17291                 skip "lustre < 2.8.54 does not support ladvise "
17292         remote_ost_nodsh && skip "remote OST with nodsh"
17293
17294         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17295
17296         ladvise_no_type willread $DIR/$tfile &&
17297                 skip "willread ladvise is not supported"
17298
17299         ladvise_no_ioctl $DIR/$tfile &&
17300                 skip "ladvise ioctl is not supported"
17301
17302         local size_mb=100
17303         local size=$((size_mb * 1048576))
17304         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17305                 error "dd to $DIR/$tfile failed"
17306
17307         lfs ladvise -a willread $DIR/$tfile ||
17308                 error "Ladvise failed with no range argument"
17309
17310         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17311                 error "Ladvise failed with no -l or -e argument"
17312
17313         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17314                 error "Ladvise failed with only -e argument"
17315
17316         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17317                 error "Ladvise failed with only -l argument"
17318
17319         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17320                 error "End offset should not be smaller than start offset"
17321
17322         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17323                 error "End offset should not be equal to start offset"
17324
17325         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17326                 error "Ladvise failed with overflowing -s argument"
17327
17328         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17329                 error "Ladvise failed with overflowing -e argument"
17330
17331         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17332                 error "Ladvise failed with overflowing -l argument"
17333
17334         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17335                 error "Ladvise succeeded with conflicting -l and -e arguments"
17336
17337         echo "Synchronous ladvise should wait"
17338         local delay=4
17339 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17340         do_nodes $(comma_list $(osts_nodes)) \
17341                 $LCTL set_param fail_val=$delay fail_loc=0x237
17342
17343         local start_ts=$SECONDS
17344         lfs ladvise -a willread $DIR/$tfile ||
17345                 error "Ladvise failed with no range argument"
17346         local end_ts=$SECONDS
17347         local inteval_ts=$((end_ts - start_ts))
17348
17349         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17350                 error "Synchronous advice didn't wait reply"
17351         fi
17352
17353         echo "Asynchronous ladvise shouldn't wait"
17354         local start_ts=$SECONDS
17355         lfs ladvise -a willread -b $DIR/$tfile ||
17356                 error "Ladvise failed with no range argument"
17357         local end_ts=$SECONDS
17358         local inteval_ts=$((end_ts - start_ts))
17359
17360         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17361                 error "Asynchronous advice blocked"
17362         fi
17363
17364         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17365         ladvise_willread_performance
17366 }
17367 run_test 255a "check 'lfs ladvise -a willread'"
17368
17369 facet_meminfo() {
17370         local facet=$1
17371         local info=$2
17372
17373         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17374 }
17375
17376 test_255b() {
17377         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17378                 skip "lustre < 2.8.54 does not support ladvise "
17379         remote_ost_nodsh && skip "remote OST with nodsh"
17380
17381         lfs setstripe -c 1 -i 0 $DIR/$tfile
17382
17383         ladvise_no_type dontneed $DIR/$tfile &&
17384                 skip "dontneed ladvise is not supported"
17385
17386         ladvise_no_ioctl $DIR/$tfile &&
17387                 skip "ladvise ioctl is not supported"
17388
17389         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17390                 [ "$ost1_FSTYPE" = "zfs" ] &&
17391                 skip "zfs-osd does not support 'ladvise dontneed'"
17392
17393         local size_mb=100
17394         local size=$((size_mb * 1048576))
17395         # In order to prevent disturbance of other processes, only check 3/4
17396         # of the memory usage
17397         local kibibytes=$((size_mb * 1024 * 3 / 4))
17398
17399         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17400                 error "dd to $DIR/$tfile failed"
17401
17402         #force write to complete before dropping OST cache & checking memory
17403         sync
17404
17405         local total=$(facet_meminfo ost1 MemTotal)
17406         echo "Total memory: $total KiB"
17407
17408         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17409         local before_read=$(facet_meminfo ost1 Cached)
17410         echo "Cache used before read: $before_read KiB"
17411
17412         lfs ladvise -a willread $DIR/$tfile ||
17413                 error "Ladvise willread failed"
17414         local after_read=$(facet_meminfo ost1 Cached)
17415         echo "Cache used after read: $after_read KiB"
17416
17417         lfs ladvise -a dontneed $DIR/$tfile ||
17418                 error "Ladvise dontneed again failed"
17419         local no_read=$(facet_meminfo ost1 Cached)
17420         echo "Cache used after dontneed ladvise: $no_read KiB"
17421
17422         if [ $total -lt $((before_read + kibibytes)) ]; then
17423                 echo "Memory is too small, abort checking"
17424                 return 0
17425         fi
17426
17427         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17428                 error "Ladvise willread should use more memory" \
17429                         "than $kibibytes KiB"
17430         fi
17431
17432         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17433                 error "Ladvise dontneed should release more memory" \
17434                         "than $kibibytes KiB"
17435         fi
17436 }
17437 run_test 255b "check 'lfs ladvise -a dontneed'"
17438
17439 test_255c() {
17440         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17441                 skip "lustre < 2.10.53 does not support lockahead"
17442
17443         local count
17444         local new_count
17445         local difference
17446         local i
17447         local rc
17448
17449         test_mkdir -p $DIR/$tdir
17450         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17451
17452         #test 10 returns only success/failure
17453         i=10
17454         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17455         rc=$?
17456         if [ $rc -eq 255 ]; then
17457                 error "Ladvise test${i} failed, ${rc}"
17458         fi
17459
17460         #test 11 counts lock enqueue requests, all others count new locks
17461         i=11
17462         count=$(do_facet ost1 \
17463                 $LCTL get_param -n ost.OSS.ost.stats)
17464         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17465
17466         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17467         rc=$?
17468         if [ $rc -eq 255 ]; then
17469                 error "Ladvise test${i} failed, ${rc}"
17470         fi
17471
17472         new_count=$(do_facet ost1 \
17473                 $LCTL get_param -n ost.OSS.ost.stats)
17474         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17475                    awk '{ print $2 }')
17476
17477         difference="$((new_count - count))"
17478         if [ $difference -ne $rc ]; then
17479                 error "Ladvise test${i}, bad enqueue count, returned " \
17480                       "${rc}, actual ${difference}"
17481         fi
17482
17483         for i in $(seq 12 21); do
17484                 # If we do not do this, we run the risk of having too many
17485                 # locks and starting lock cancellation while we are checking
17486                 # lock counts.
17487                 cancel_lru_locks osc
17488
17489                 count=$($LCTL get_param -n \
17490                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17491
17492                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17493                 rc=$?
17494                 if [ $rc -eq 255 ]; then
17495                         error "Ladvise test ${i} failed, ${rc}"
17496                 fi
17497
17498                 new_count=$($LCTL get_param -n \
17499                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17500                 difference="$((new_count - count))"
17501
17502                 # Test 15 output is divided by 100 to map down to valid return
17503                 if [ $i -eq 15 ]; then
17504                         rc="$((rc * 100))"
17505                 fi
17506
17507                 if [ $difference -ne $rc ]; then
17508                         error "Ladvise test ${i}, bad lock count, returned " \
17509                               "${rc}, actual ${difference}"
17510                 fi
17511         done
17512
17513         #test 22 returns only success/failure
17514         i=22
17515         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17516         rc=$?
17517         if [ $rc -eq 255 ]; then
17518                 error "Ladvise test${i} failed, ${rc}"
17519         fi
17520 }
17521 run_test 255c "suite of ladvise lockahead tests"
17522
17523 test_256() {
17524         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17525         remote_mds_nodsh && skip "remote MDS with nodsh"
17526         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17527         changelog_users $SINGLEMDS | grep "^cl" &&
17528                 skip "active changelog user"
17529
17530         local cl_user
17531         local cat_sl
17532         local mdt_dev
17533
17534         mdt_dev=$(mdsdevname 1)
17535         echo $mdt_dev
17536
17537         changelog_register || error "changelog_register failed"
17538
17539         rm -rf $DIR/$tdir
17540         mkdir -p $DIR/$tdir
17541
17542         changelog_clear 0 || error "changelog_clear failed"
17543
17544         # change something
17545         touch $DIR/$tdir/{1..10}
17546
17547         # stop the MDT
17548         stop $SINGLEMDS || error "Fail to stop MDT"
17549
17550         # remount the MDT
17551
17552         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17553
17554         #after mount new plainllog is used
17555         touch $DIR/$tdir/{11..19}
17556         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
17557         stack_trap "rm -f $tmpfile"
17558         cat_sl=$(do_facet $SINGLEMDS "sync; \
17559                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17560                  llog_reader $tmpfile | grep -c type=1064553b")
17561         do_facet $SINGLEMDS llog_reader $tmpfile
17562
17563         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17564
17565         changelog_clear 0 || error "changelog_clear failed"
17566
17567         cat_sl=$(do_facet $SINGLEMDS "sync; \
17568                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17569                  llog_reader $tmpfile | grep -c type=1064553b")
17570
17571         if (( cat_sl == 2 )); then
17572                 error "Empty plain llog was not deleted from changelog catalog"
17573         elif (( cat_sl != 1 )); then
17574                 error "Active plain llog shouldn't be deleted from catalog"
17575         fi
17576 }
17577 run_test 256 "Check llog delete for empty and not full state"
17578
17579 test_257() {
17580         remote_mds_nodsh && skip "remote MDS with nodsh"
17581         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17582                 skip "Need MDS version at least 2.8.55"
17583
17584         test_mkdir $DIR/$tdir
17585
17586         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17587                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17588         stat $DIR/$tdir
17589
17590 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17591         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17592         local facet=mds$((mdtidx + 1))
17593         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17594         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17595
17596         stop $facet || error "stop MDS failed"
17597         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17598                 error "start MDS fail"
17599         wait_recovery_complete $facet
17600 }
17601 run_test 257 "xattr locks are not lost"
17602
17603 # Verify we take the i_mutex when security requires it
17604 test_258a() {
17605 #define OBD_FAIL_IMUTEX_SEC 0x141c
17606         $LCTL set_param fail_loc=0x141c
17607         touch $DIR/$tfile
17608         chmod u+s $DIR/$tfile
17609         chmod a+rwx $DIR/$tfile
17610         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17611         RC=$?
17612         if [ $RC -ne 0 ]; then
17613                 error "error, failed to take i_mutex, rc=$?"
17614         fi
17615         rm -f $DIR/$tfile
17616 }
17617 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17618
17619 # Verify we do NOT take the i_mutex in the normal case
17620 test_258b() {
17621 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17622         $LCTL set_param fail_loc=0x141d
17623         touch $DIR/$tfile
17624         chmod a+rwx $DIR
17625         chmod a+rw $DIR/$tfile
17626         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17627         RC=$?
17628         if [ $RC -ne 0 ]; then
17629                 error "error, took i_mutex unnecessarily, rc=$?"
17630         fi
17631         rm -f $DIR/$tfile
17632
17633 }
17634 run_test 258b "verify i_mutex security behavior"
17635
17636 test_259() {
17637         local file=$DIR/$tfile
17638         local before
17639         local after
17640
17641         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17642
17643         stack_trap "rm -f $file" EXIT
17644
17645         wait_delete_completed
17646         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17647         echo "before: $before"
17648
17649         $LFS setstripe -i 0 -c 1 $file
17650         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17651         sync_all_data
17652         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17653         echo "after write: $after"
17654
17655 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17656         do_facet ost1 $LCTL set_param fail_loc=0x2301
17657         $TRUNCATE $file 0
17658         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17659         echo "after truncate: $after"
17660
17661         stop ost1
17662         do_facet ost1 $LCTL set_param fail_loc=0
17663         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17664         sleep 2
17665         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17666         echo "after restart: $after"
17667         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17668                 error "missing truncate?"
17669
17670         return 0
17671 }
17672 run_test 259 "crash at delayed truncate"
17673
17674 test_260() {
17675 #define OBD_FAIL_MDC_CLOSE               0x806
17676         $LCTL set_param fail_loc=0x80000806
17677         touch $DIR/$tfile
17678
17679 }
17680 run_test 260 "Check mdc_close fail"
17681
17682 ### Data-on-MDT sanity tests ###
17683 test_270a() {
17684         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17685                 skip "Need MDS version at least 2.10.55 for DoM"
17686
17687         # create DoM file
17688         local dom=$DIR/$tdir/dom_file
17689         local tmp=$DIR/$tdir/tmp_file
17690
17691         mkdir -p $DIR/$tdir
17692
17693         # basic checks for DoM component creation
17694         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17695                 error "Can set MDT layout to non-first entry"
17696
17697         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17698                 error "Can define multiple entries as MDT layout"
17699
17700         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17701
17702         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17703         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17704         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17705
17706         local mdtidx=$($LFS getstripe -m $dom)
17707         local mdtname=MDT$(printf %04x $mdtidx)
17708         local facet=mds$((mdtidx + 1))
17709         local space_check=1
17710
17711         # Skip free space checks with ZFS
17712         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17713
17714         # write
17715         sync
17716         local size_tmp=$((65536 * 3))
17717         local mdtfree1=$(do_facet $facet \
17718                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17719
17720         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17721         # check also direct IO along write
17722         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17723         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17724         sync
17725         cmp $tmp $dom || error "file data is different"
17726         [ $(stat -c%s $dom) == $size_tmp ] ||
17727                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17728         if [ $space_check == 1 ]; then
17729                 local mdtfree2=$(do_facet $facet \
17730                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17731
17732                 # increase in usage from by $size_tmp
17733                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17734                         error "MDT free space wrong after write: " \
17735                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17736         fi
17737
17738         # truncate
17739         local size_dom=10000
17740
17741         $TRUNCATE $dom $size_dom
17742         [ $(stat -c%s $dom) == $size_dom ] ||
17743                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
17744         if [ $space_check == 1 ]; then
17745                 mdtfree1=$(do_facet $facet \
17746                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17747                 # decrease in usage from $size_tmp to new $size_dom
17748                 [ $(($mdtfree1 - $mdtfree2)) -ge \
17749                   $(((size_tmp - size_dom) / 1024)) ] ||
17750                         error "MDT free space is wrong after truncate: " \
17751                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
17752         fi
17753
17754         # append
17755         cat $tmp >> $dom
17756         sync
17757         size_dom=$((size_dom + size_tmp))
17758         [ $(stat -c%s $dom) == $size_dom ] ||
17759                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
17760         if [ $space_check == 1 ]; then
17761                 mdtfree2=$(do_facet $facet \
17762                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17763                 # increase in usage by $size_tmp from previous
17764                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
17765                         error "MDT free space is wrong after append: " \
17766                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
17767         fi
17768
17769         # delete
17770         rm $dom
17771         if [ $space_check == 1 ]; then
17772                 mdtfree1=$(do_facet $facet \
17773                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
17774                 # decrease in usage by $size_dom from previous
17775                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
17776                         error "MDT free space is wrong after removal: " \
17777                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
17778         fi
17779
17780         # combined striping
17781         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
17782                 error "Can't create DoM + OST striping"
17783
17784         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
17785         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17786         # check also direct IO along write
17787         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17788         sync
17789         cmp $tmp $dom || error "file data is different"
17790         [ $(stat -c%s $dom) == $size_tmp ] ||
17791                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17792         rm $dom $tmp
17793
17794         return 0
17795 }
17796 run_test 270a "DoM: basic functionality tests"
17797
17798 test_270b() {
17799         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17800                 skip "Need MDS version at least 2.10.55"
17801
17802         local dom=$DIR/$tdir/dom_file
17803         local max_size=1048576
17804
17805         mkdir -p $DIR/$tdir
17806         $LFS setstripe -E $max_size -L mdt $dom
17807
17808         # truncate over the limit
17809         $TRUNCATE $dom $(($max_size + 1)) &&
17810                 error "successful truncate over the maximum size"
17811         # write over the limit
17812         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
17813                 error "successful write over the maximum size"
17814         # append over the limit
17815         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
17816         echo "12345" >> $dom && error "successful append over the maximum size"
17817         rm $dom
17818
17819         return 0
17820 }
17821 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
17822
17823 test_270c() {
17824         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17825                 skip "Need MDS version at least 2.10.55"
17826
17827         mkdir -p $DIR/$tdir
17828         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17829
17830         # check files inherit DoM EA
17831         touch $DIR/$tdir/first
17832         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
17833                 error "bad pattern"
17834         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
17835                 error "bad stripe count"
17836         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
17837                 error "bad stripe size"
17838
17839         # check directory inherits DoM EA and uses it as default
17840         mkdir $DIR/$tdir/subdir
17841         touch $DIR/$tdir/subdir/second
17842         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
17843                 error "bad pattern in sub-directory"
17844         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
17845                 error "bad stripe count in sub-directory"
17846         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
17847                 error "bad stripe size in sub-directory"
17848         return 0
17849 }
17850 run_test 270c "DoM: DoM EA inheritance tests"
17851
17852 test_270d() {
17853         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17854                 skip "Need MDS version at least 2.10.55"
17855
17856         mkdir -p $DIR/$tdir
17857         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
17858
17859         # inherit default DoM striping
17860         mkdir $DIR/$tdir/subdir
17861         touch $DIR/$tdir/subdir/f1
17862
17863         # change default directory striping
17864         $LFS setstripe -c 1 $DIR/$tdir/subdir
17865         touch $DIR/$tdir/subdir/f2
17866         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
17867                 error "wrong default striping in file 2"
17868         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
17869                 error "bad pattern in file 2"
17870         return 0
17871 }
17872 run_test 270d "DoM: change striping from DoM to RAID0"
17873
17874 test_270e() {
17875         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17876                 skip "Need MDS version at least 2.10.55"
17877
17878         mkdir -p $DIR/$tdir/dom
17879         mkdir -p $DIR/$tdir/norm
17880         DOMFILES=20
17881         NORMFILES=10
17882         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
17883         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
17884
17885         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
17886         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
17887
17888         # find DoM files by layout
17889         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
17890         [ $NUM -eq  $DOMFILES ] ||
17891                 error "lfs find -L: found $NUM, expected $DOMFILES"
17892         echo "Test 1: lfs find 20 DOM files by layout: OK"
17893
17894         # there should be 1 dir with default DOM striping
17895         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
17896         [ $NUM -eq  1 ] ||
17897                 error "lfs find -L: found $NUM, expected 1 dir"
17898         echo "Test 2: lfs find 1 DOM dir by layout: OK"
17899
17900         # find DoM files by stripe size
17901         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
17902         [ $NUM -eq  $DOMFILES ] ||
17903                 error "lfs find -S: found $NUM, expected $DOMFILES"
17904         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
17905
17906         # find files by stripe offset except DoM files
17907         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
17908         [ $NUM -eq  $NORMFILES ] ||
17909                 error "lfs find -i: found $NUM, expected $NORMFILES"
17910         echo "Test 5: lfs find no DOM files by stripe index: OK"
17911         return 0
17912 }
17913 run_test 270e "DoM: lfs find with DoM files test"
17914
17915 test_270f() {
17916         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17917                 skip "Need MDS version at least 2.10.55"
17918
17919         local mdtname=${FSNAME}-MDT0000-mdtlov
17920         local dom=$DIR/$tdir/dom_file
17921         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
17922                                                 lod.$mdtname.dom_stripesize)
17923         local dom_limit=131072
17924
17925         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
17926         local dom_current=$(do_facet mds1 $LCTL get_param -n \
17927                                                 lod.$mdtname.dom_stripesize)
17928         [ ${dom_limit} -eq ${dom_current} ] ||
17929                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
17930
17931         $LFS mkdir -i 0 -c 1 $DIR/$tdir
17932         $LFS setstripe -d $DIR/$tdir
17933         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
17934                 error "Can't set directory default striping"
17935
17936         # exceed maximum stripe size
17937         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17938                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
17939         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
17940                 error "Able to create DoM component size more than LOD limit"
17941
17942         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
17943         dom_current=$(do_facet mds1 $LCTL get_param -n \
17944                                                 lod.$mdtname.dom_stripesize)
17945         [ 0 -eq ${dom_current} ] ||
17946                 error "Can't set zero DoM stripe limit"
17947         rm $dom
17948
17949         # attempt to create DoM file on server with disabled DoM should
17950         # remove DoM entry from layout and be succeed
17951         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
17952                 error "Can't create DoM file (DoM is disabled)"
17953         [ $($LFS getstripe -L $dom) == "mdt" ] &&
17954                 error "File has DoM component while DoM is disabled"
17955         rm $dom
17956
17957         # attempt to create DoM file with only DoM stripe should return error
17958         $LFS setstripe -E $dom_limit -L mdt $dom &&
17959                 error "Able to create DoM-only file while DoM is disabled"
17960
17961         # too low values to be aligned with smallest stripe size 64K
17962         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
17963         dom_current=$(do_facet mds1 $LCTL get_param -n \
17964                                                 lod.$mdtname.dom_stripesize)
17965         [ 30000 -eq ${dom_current} ] &&
17966                 error "Can set too small DoM stripe limit"
17967
17968         # 64K is a minimal stripe size in Lustre, expect limit of that size
17969         [ 65536 -eq ${dom_current} ] ||
17970                 error "Limit is not set to 64K but ${dom_current}"
17971
17972         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
17973         dom_current=$(do_facet mds1 $LCTL get_param -n \
17974                                                 lod.$mdtname.dom_stripesize)
17975         echo $dom_current
17976         [ 2147483648 -eq ${dom_current} ] &&
17977                 error "Can set too large DoM stripe limit"
17978
17979         do_facet mds1 $LCTL set_param -n \
17980                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
17981         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
17982                 error "Can't create DoM component size after limit change"
17983         do_facet mds1 $LCTL set_param -n \
17984                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
17985         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
17986                 error "Can't create DoM file after limit decrease"
17987         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
17988                 error "Can create big DoM component after limit decrease"
17989         touch ${dom}_def ||
17990                 error "Can't create file with old default layout"
17991
17992         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
17993         return 0
17994 }
17995 run_test 270f "DoM: maximum DoM stripe size checks"
17996
17997 test_271a() {
17998         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17999                 skip "Need MDS version at least 2.10.55"
18000
18001         local dom=$DIR/$tdir/dom
18002
18003         mkdir -p $DIR/$tdir
18004
18005         $LFS setstripe -E 1024K -L mdt $dom
18006
18007         lctl set_param -n mdc.*.stats=clear
18008         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18009         cat $dom > /dev/null
18010         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18011         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18012         ls $dom
18013         rm -f $dom
18014 }
18015 run_test 271a "DoM: data is cached for read after write"
18016
18017 test_271b() {
18018         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18019                 skip "Need MDS version at least 2.10.55"
18020
18021         local dom=$DIR/$tdir/dom
18022
18023         mkdir -p $DIR/$tdir
18024
18025         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18026
18027         lctl set_param -n mdc.*.stats=clear
18028         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18029         cancel_lru_locks mdc
18030         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18031         # second stat to check size is cached on client
18032         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18033         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18034         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18035         rm -f $dom
18036 }
18037 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18038
18039 test_271ba() {
18040         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18041                 skip "Need MDS version at least 2.10.55"
18042
18043         local dom=$DIR/$tdir/dom
18044
18045         mkdir -p $DIR/$tdir
18046
18047         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18048
18049         lctl set_param -n mdc.*.stats=clear
18050         lctl set_param -n osc.*.stats=clear
18051         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18052         cancel_lru_locks mdc
18053         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18054         # second stat to check size is cached on client
18055         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18056         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18057         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18058         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18059         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18060         rm -f $dom
18061 }
18062 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18063
18064
18065 get_mdc_stats() {
18066         local mdtidx=$1
18067         local param=$2
18068         local mdt=MDT$(printf %04x $mdtidx)
18069
18070         if [ -z $param ]; then
18071                 lctl get_param -n mdc.*$mdt*.stats
18072         else
18073                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18074         fi
18075 }
18076
18077 test_271c() {
18078         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18079                 skip "Need MDS version at least 2.10.55"
18080
18081         local dom=$DIR/$tdir/dom
18082
18083         mkdir -p $DIR/$tdir
18084
18085         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18086
18087         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18088         local facet=mds$((mdtidx + 1))
18089
18090         cancel_lru_locks mdc
18091         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18092         createmany -o $dom 1000
18093         lctl set_param -n mdc.*.stats=clear
18094         smalliomany -w $dom 1000 200
18095         get_mdc_stats $mdtidx
18096         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18097         # Each file has 1 open, 1 IO enqueues, total 2000
18098         # but now we have also +1 getxattr for security.capability, total 3000
18099         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18100         unlinkmany $dom 1000
18101
18102         cancel_lru_locks mdc
18103         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18104         createmany -o $dom 1000
18105         lctl set_param -n mdc.*.stats=clear
18106         smalliomany -w $dom 1000 200
18107         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18108         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18109         # for OPEN and IO lock.
18110         [ $((enq - enq_2)) -ge 1000 ] ||
18111                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18112         unlinkmany $dom 1000
18113         return 0
18114 }
18115 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18116
18117 cleanup_271def_tests() {
18118         trap 0
18119         rm -f $1
18120 }
18121
18122 test_271d() {
18123         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18124                 skip "Need MDS version at least 2.10.57"
18125
18126         local dom=$DIR/$tdir/dom
18127         local tmp=$TMP/$tfile
18128         trap "cleanup_271def_tests $tmp" EXIT
18129
18130         mkdir -p $DIR/$tdir
18131
18132         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18133
18134         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18135
18136         cancel_lru_locks mdc
18137         dd if=/dev/urandom of=$tmp bs=1000 count=1
18138         dd if=$tmp of=$dom bs=1000 count=1
18139         cancel_lru_locks mdc
18140
18141         cat /etc/hosts >> $tmp
18142         lctl set_param -n mdc.*.stats=clear
18143
18144         # append data to the same file it should update local page
18145         echo "Append to the same page"
18146         cat /etc/hosts >> $dom
18147         local num=$(get_mdc_stats $mdtidx ost_read)
18148         local ra=$(get_mdc_stats $mdtidx req_active)
18149         local rw=$(get_mdc_stats $mdtidx req_waittime)
18150
18151         [ -z $num ] || error "$num READ RPC occured"
18152         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18153         echo "... DONE"
18154
18155         # compare content
18156         cmp $tmp $dom || error "file miscompare"
18157
18158         cancel_lru_locks mdc
18159         lctl set_param -n mdc.*.stats=clear
18160
18161         echo "Open and read file"
18162         cat $dom > /dev/null
18163         local num=$(get_mdc_stats $mdtidx ost_read)
18164         local ra=$(get_mdc_stats $mdtidx req_active)
18165         local rw=$(get_mdc_stats $mdtidx req_waittime)
18166
18167         [ -z $num ] || error "$num READ RPC occured"
18168         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18169         echo "... DONE"
18170
18171         # compare content
18172         cmp $tmp $dom || error "file miscompare"
18173
18174         return 0
18175 }
18176 run_test 271d "DoM: read on open (1K file in reply buffer)"
18177
18178 test_271f() {
18179         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18180                 skip "Need MDS version at least 2.10.57"
18181
18182         local dom=$DIR/$tdir/dom
18183         local tmp=$TMP/$tfile
18184         trap "cleanup_271def_tests $tmp" EXIT
18185
18186         mkdir -p $DIR/$tdir
18187
18188         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18189
18190         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18191
18192         cancel_lru_locks mdc
18193         dd if=/dev/urandom of=$tmp bs=200000 count=1
18194         dd if=$tmp of=$dom bs=200000 count=1
18195         cancel_lru_locks mdc
18196         cat /etc/hosts >> $tmp
18197         lctl set_param -n mdc.*.stats=clear
18198
18199         echo "Append to the same page"
18200         cat /etc/hosts >> $dom
18201         local num=$(get_mdc_stats $mdtidx ost_read)
18202         local ra=$(get_mdc_stats $mdtidx req_active)
18203         local rw=$(get_mdc_stats $mdtidx req_waittime)
18204
18205         [ -z $num ] || error "$num READ RPC occured"
18206         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18207         echo "... DONE"
18208
18209         # compare content
18210         cmp $tmp $dom || error "file miscompare"
18211
18212         cancel_lru_locks mdc
18213         lctl set_param -n mdc.*.stats=clear
18214
18215         echo "Open and read file"
18216         cat $dom > /dev/null
18217         local num=$(get_mdc_stats $mdtidx ost_read)
18218         local ra=$(get_mdc_stats $mdtidx req_active)
18219         local rw=$(get_mdc_stats $mdtidx req_waittime)
18220
18221         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18222         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18223         echo "... DONE"
18224
18225         # compare content
18226         cmp $tmp $dom || error "file miscompare"
18227
18228         return 0
18229 }
18230 run_test 271f "DoM: read on open (200K file and read tail)"
18231
18232 test_271g() {
18233         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18234                 skip "Skipping due to old client or server version"
18235
18236         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18237         # to get layout
18238         $CHECKSTAT -t file $DIR1/$tfile
18239
18240         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18241         MULTIOP_PID=$!
18242         sleep 1
18243         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18244         $LCTL set_param fail_loc=0x80000314
18245         rm $DIR1/$tfile || error "Unlink fails"
18246         RC=$?
18247         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18248         [ $RC -eq 0 ] || error "Failed write to stale object"
18249 }
18250 run_test 271g "Discard DoM data vs client flush race"
18251
18252 test_272a() {
18253         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18254                 skip "Need MDS version at least 2.11.50"
18255
18256         local dom=$DIR/$tdir/dom
18257         mkdir -p $DIR/$tdir
18258
18259         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18260         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18261                 error "failed to write data into $dom"
18262         local old_md5=$(md5sum $dom)
18263
18264         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18265                 error "failed to migrate to the same DoM component"
18266
18267         local new_md5=$(md5sum $dom)
18268
18269         [ "$old_md5" == "$new_md5" ] ||
18270                 error "md5sum differ: $old_md5, $new_md5"
18271
18272         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18273                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18274 }
18275 run_test 272a "DoM migration: new layout with the same DOM component"
18276
18277 test_272b() {
18278         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18279                 skip "Need MDS version at least 2.11.50"
18280
18281         local dom=$DIR/$tdir/dom
18282         mkdir -p $DIR/$tdir
18283         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18284
18285         local mdtidx=$($LFS getstripe -m $dom)
18286         local mdtname=MDT$(printf %04x $mdtidx)
18287         local facet=mds$((mdtidx + 1))
18288
18289         local mdtfree1=$(do_facet $facet \
18290                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18291         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18292                 error "failed to write data into $dom"
18293         local old_md5=$(md5sum $dom)
18294         cancel_lru_locks mdc
18295         local mdtfree1=$(do_facet $facet \
18296                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18297
18298         $LFS migrate -c2 $dom ||
18299                 error "failed to migrate to the new composite layout"
18300         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18301                 error "MDT stripe was not removed"
18302
18303         cancel_lru_locks mdc
18304         local new_md5=$(md5sum $dom)
18305         [ "$old_md5" != "$new_md5" ] &&
18306                 error "$old_md5 != $new_md5"
18307
18308         # Skip free space checks with ZFS
18309         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18310                 local mdtfree2=$(do_facet $facet \
18311                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18312                 [ $mdtfree2 -gt $mdtfree1 ] ||
18313                         error "MDT space is not freed after migration"
18314         fi
18315         return 0
18316 }
18317 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18318
18319 test_272c() {
18320         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18321                 skip "Need MDS version at least 2.11.50"
18322
18323         local dom=$DIR/$tdir/$tfile
18324         mkdir -p $DIR/$tdir
18325         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18326
18327         local mdtidx=$($LFS getstripe -m $dom)
18328         local mdtname=MDT$(printf %04x $mdtidx)
18329         local facet=mds$((mdtidx + 1))
18330
18331         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18332                 error "failed to write data into $dom"
18333         local old_md5=$(md5sum $dom)
18334         cancel_lru_locks mdc
18335         local mdtfree1=$(do_facet $facet \
18336                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18337
18338         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18339                 error "failed to migrate to the new composite layout"
18340         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18341                 error "MDT stripe was not removed"
18342
18343         cancel_lru_locks mdc
18344         local new_md5=$(md5sum $dom)
18345         [ "$old_md5" != "$new_md5" ] &&
18346                 error "$old_md5 != $new_md5"
18347
18348         # Skip free space checks with ZFS
18349         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18350                 local mdtfree2=$(do_facet $facet \
18351                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18352                 [ $mdtfree2 -gt $mdtfree1 ] ||
18353                         error "MDS space is not freed after migration"
18354         fi
18355         return 0
18356 }
18357 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18358
18359 test_273a() {
18360         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18361                 skip "Need MDS version at least 2.11.50"
18362
18363         # Layout swap cannot be done if either file has DOM component,
18364         # this will never be supported, migration should be used instead
18365
18366         local dom=$DIR/$tdir/$tfile
18367         mkdir -p $DIR/$tdir
18368
18369         $LFS setstripe -c2 ${dom}_plain
18370         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18371         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18372                 error "can swap layout with DoM component"
18373         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18374                 error "can swap layout with DoM component"
18375
18376         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18377         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18378                 error "can swap layout with DoM component"
18379         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18380                 error "can swap layout with DoM component"
18381         return 0
18382 }
18383 run_test 273a "DoM: layout swapping should fail with DOM"
18384
18385 test_275() {
18386         remote_ost_nodsh && skip "remote OST with nodsh"
18387         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18388                 skip "Need OST version >= 2.10.57"
18389
18390         local file=$DIR/$tfile
18391         local oss
18392
18393         oss=$(comma_list $(osts_nodes))
18394
18395         dd if=/dev/urandom of=$file bs=1M count=2 ||
18396                 error "failed to create a file"
18397         cancel_lru_locks osc
18398
18399         #lock 1
18400         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18401                 error "failed to read a file"
18402
18403 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18404         $LCTL set_param fail_loc=0x8000031f
18405
18406         cancel_lru_locks osc &
18407         sleep 1
18408
18409 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18410         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18411         #IO takes another lock, but matches the PENDING one
18412         #and places it to the IO RPC
18413         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18414                 error "failed to read a file with PENDING lock"
18415 }
18416 run_test 275 "Read on a canceled duplicate lock"
18417
18418 test_276() {
18419         remote_ost_nodsh && skip "remote OST with nodsh"
18420         local pid
18421
18422         do_facet ost1 "(while true; do \
18423                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18424                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18425         pid=$!
18426
18427         for LOOP in $(seq 20); do
18428                 stop ost1
18429                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18430         done
18431         kill -9 $pid
18432         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18433                 rm $TMP/sanity_276_pid"
18434 }
18435 run_test 276 "Race between mount and obd_statfs"
18436
18437 test_277() {
18438         $LCTL set_param ldlm.namespaces.*.lru_size=0
18439         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
18440         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18441                         grep ^used_mb | awk '{print $2}')
18442         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
18443         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
18444                 oflag=direct conv=notrunc
18445         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18446                         grep ^used_mb | awk '{print $2}')
18447         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
18448 }
18449 run_test 277 "Direct IO shall drop page cache"
18450
18451 cleanup_test_300() {
18452         trap 0
18453         umask $SAVE_UMASK
18454 }
18455 test_striped_dir() {
18456         local mdt_index=$1
18457         local stripe_count
18458         local stripe_index
18459
18460         mkdir -p $DIR/$tdir
18461
18462         SAVE_UMASK=$(umask)
18463         trap cleanup_test_300 RETURN EXIT
18464
18465         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18466                                                 $DIR/$tdir/striped_dir ||
18467                 error "set striped dir error"
18468
18469         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18470         [ "$mode" = "755" ] || error "expect 755 got $mode"
18471
18472         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18473                 error "getdirstripe failed"
18474         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18475         if [ "$stripe_count" != "2" ]; then
18476                 error "1:stripe_count is $stripe_count, expect 2"
18477         fi
18478         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18479         if [ "$stripe_count" != "2" ]; then
18480                 error "2:stripe_count is $stripe_count, expect 2"
18481         fi
18482
18483         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18484         if [ "$stripe_index" != "$mdt_index" ]; then
18485                 error "stripe_index is $stripe_index, expect $mdt_index"
18486         fi
18487
18488         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18489                 error "nlink error after create striped dir"
18490
18491         mkdir $DIR/$tdir/striped_dir/a
18492         mkdir $DIR/$tdir/striped_dir/b
18493
18494         stat $DIR/$tdir/striped_dir/a ||
18495                 error "create dir under striped dir failed"
18496         stat $DIR/$tdir/striped_dir/b ||
18497                 error "create dir under striped dir failed"
18498
18499         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18500                 error "nlink error after mkdir"
18501
18502         rmdir $DIR/$tdir/striped_dir/a
18503         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18504                 error "nlink error after rmdir"
18505
18506         rmdir $DIR/$tdir/striped_dir/b
18507         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18508                 error "nlink error after rmdir"
18509
18510         chattr +i $DIR/$tdir/striped_dir
18511         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18512                 error "immutable flags not working under striped dir!"
18513         chattr -i $DIR/$tdir/striped_dir
18514
18515         rmdir $DIR/$tdir/striped_dir ||
18516                 error "rmdir striped dir error"
18517
18518         cleanup_test_300
18519
18520         true
18521 }
18522
18523 test_300a() {
18524         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18525                 skip "skipped for lustre < 2.7.0"
18526         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18527         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18528
18529         test_striped_dir 0 || error "failed on striped dir on MDT0"
18530         test_striped_dir 1 || error "failed on striped dir on MDT0"
18531 }
18532 run_test 300a "basic striped dir sanity test"
18533
18534 test_300b() {
18535         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18536                 skip "skipped for lustre < 2.7.0"
18537         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18538         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18539
18540         local i
18541         local mtime1
18542         local mtime2
18543         local mtime3
18544
18545         test_mkdir $DIR/$tdir || error "mkdir fail"
18546         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18547                 error "set striped dir error"
18548         for i in {0..9}; do
18549                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18550                 sleep 1
18551                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18552                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18553                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18554                 sleep 1
18555                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18556                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18557                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18558         done
18559         true
18560 }
18561 run_test 300b "check ctime/mtime for striped dir"
18562
18563 test_300c() {
18564         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18565                 skip "skipped for lustre < 2.7.0"
18566         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18567         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18568
18569         local file_count
18570
18571         mkdir -p $DIR/$tdir
18572         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18573                 error "set striped dir error"
18574
18575         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18576                 error "chown striped dir failed"
18577
18578         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18579                 error "create 5k files failed"
18580
18581         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18582
18583         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18584
18585         rm -rf $DIR/$tdir
18586 }
18587 run_test 300c "chown && check ls under striped directory"
18588
18589 test_300d() {
18590         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18591                 skip "skipped for lustre < 2.7.0"
18592         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18593         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18594
18595         local stripe_count
18596         local file
18597
18598         mkdir -p $DIR/$tdir
18599         $LFS setstripe -c 2 $DIR/$tdir
18600
18601         #local striped directory
18602         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18603                 error "set striped dir error"
18604         createmany -o $DIR/$tdir/striped_dir/f 10 ||
18605                 error "create 10 files failed"
18606
18607         #remote striped directory
18608         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
18609                 error "set striped dir error"
18610         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
18611                 error "create 10 files failed"
18612
18613         for file in $(find $DIR/$tdir); do
18614                 stripe_count=$($LFS getstripe -c $file)
18615                 [ $stripe_count -eq 2 ] ||
18616                         error "wrong stripe $stripe_count for $file"
18617         done
18618
18619         rm -rf $DIR/$tdir
18620 }
18621 run_test 300d "check default stripe under striped directory"
18622
18623 test_300e() {
18624         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18625                 skip "Need MDS version at least 2.7.55"
18626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18627         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18628
18629         local stripe_count
18630         local file
18631
18632         mkdir -p $DIR/$tdir
18633
18634         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18635                 error "set striped dir error"
18636
18637         touch $DIR/$tdir/striped_dir/a
18638         touch $DIR/$tdir/striped_dir/b
18639         touch $DIR/$tdir/striped_dir/c
18640
18641         mkdir $DIR/$tdir/striped_dir/dir_a
18642         mkdir $DIR/$tdir/striped_dir/dir_b
18643         mkdir $DIR/$tdir/striped_dir/dir_c
18644
18645         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
18646                 error "set striped adir under striped dir error"
18647
18648         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
18649                 error "set striped bdir under striped dir error"
18650
18651         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
18652                 error "set striped cdir under striped dir error"
18653
18654         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
18655                 error "rename dir under striped dir fails"
18656
18657         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
18658                 error "rename dir under different stripes fails"
18659
18660         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
18661                 error "rename file under striped dir should succeed"
18662
18663         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
18664                 error "rename dir under striped dir should succeed"
18665
18666         rm -rf $DIR/$tdir
18667 }
18668 run_test 300e "check rename under striped directory"
18669
18670 test_300f() {
18671         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18672         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18673         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18674                 skip "Need MDS version at least 2.7.55"
18675
18676         local stripe_count
18677         local file
18678
18679         rm -rf $DIR/$tdir
18680         mkdir -p $DIR/$tdir
18681
18682         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18683                 error "set striped dir error"
18684
18685         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
18686                 error "set striped dir error"
18687
18688         touch $DIR/$tdir/striped_dir/a
18689         mkdir $DIR/$tdir/striped_dir/dir_a
18690         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
18691                 error "create striped dir under striped dir fails"
18692
18693         touch $DIR/$tdir/striped_dir1/b
18694         mkdir $DIR/$tdir/striped_dir1/dir_b
18695         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
18696                 error "create striped dir under striped dir fails"
18697
18698         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
18699                 error "rename dir under different striped dir should fail"
18700
18701         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
18702                 error "rename striped dir under diff striped dir should fail"
18703
18704         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
18705                 error "rename file under diff striped dirs fails"
18706
18707         rm -rf $DIR/$tdir
18708 }
18709 run_test 300f "check rename cross striped directory"
18710
18711 test_300_check_default_striped_dir()
18712 {
18713         local dirname=$1
18714         local default_count=$2
18715         local default_index=$3
18716         local stripe_count
18717         local stripe_index
18718         local dir_stripe_index
18719         local dir
18720
18721         echo "checking $dirname $default_count $default_index"
18722         $LFS setdirstripe -D -c $default_count -i $default_index \
18723                                 -t all_char $DIR/$tdir/$dirname ||
18724                 error "set default stripe on striped dir error"
18725         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
18726         [ $stripe_count -eq $default_count ] ||
18727                 error "expect $default_count get $stripe_count for $dirname"
18728
18729         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
18730         [ $stripe_index -eq $default_index ] ||
18731                 error "expect $default_index get $stripe_index for $dirname"
18732
18733         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
18734                                                 error "create dirs failed"
18735
18736         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
18737         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
18738         for dir in $(find $DIR/$tdir/$dirname/*); do
18739                 stripe_count=$($LFS getdirstripe -c $dir)
18740                 [ $stripe_count -eq $default_count ] ||
18741                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
18742                 error "stripe count $default_count != $stripe_count for $dir"
18743
18744                 stripe_index=$($LFS getdirstripe -i $dir)
18745                 [ $default_index -eq -1 ] ||
18746                         [ $stripe_index -eq $default_index ] ||
18747                         error "$stripe_index != $default_index for $dir"
18748
18749                 #check default stripe
18750                 stripe_count=$($LFS getdirstripe -D -c $dir)
18751                 [ $stripe_count -eq $default_count ] ||
18752                 error "default count $default_count != $stripe_count for $dir"
18753
18754                 stripe_index=$($LFS getdirstripe -D -i $dir)
18755                 [ $stripe_index -eq $default_index ] ||
18756                 error "default index $default_index != $stripe_index for $dir"
18757         done
18758         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
18759 }
18760
18761 test_300g() {
18762         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18763         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18764                 skip "Need MDS version at least 2.7.55"
18765
18766         local dir
18767         local stripe_count
18768         local stripe_index
18769
18770         mkdir $DIR/$tdir
18771         mkdir $DIR/$tdir/normal_dir
18772
18773         #Checking when client cache stripe index
18774         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
18775         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
18776                 error "create striped_dir failed"
18777
18778         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
18779                 error "create dir0 fails"
18780         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
18781         [ $stripe_index -eq 0 ] ||
18782                 error "dir0 expect index 0 got $stripe_index"
18783
18784         mkdir $DIR/$tdir/striped_dir/dir1 ||
18785                 error "create dir1 fails"
18786         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
18787         [ $stripe_index -eq 1 ] ||
18788                 error "dir1 expect index 1 got $stripe_index"
18789
18790         #check default stripe count/stripe index
18791         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
18792         test_300_check_default_striped_dir normal_dir 1 0
18793         test_300_check_default_striped_dir normal_dir 2 1
18794         test_300_check_default_striped_dir normal_dir 2 -1
18795
18796         #delete default stripe information
18797         echo "delete default stripeEA"
18798         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
18799                 error "set default stripe on striped dir error"
18800
18801         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
18802         for dir in $(find $DIR/$tdir/normal_dir/*); do
18803                 stripe_count=$($LFS getdirstripe -c $dir)
18804                 [ $stripe_count -eq 0 ] ||
18805                         error "expect 1 get $stripe_count for $dir"
18806                 stripe_index=$($LFS getdirstripe -i $dir)
18807                 [ $stripe_index -eq 0 ] ||
18808                         error "expect 0 get $stripe_index for $dir"
18809         done
18810 }
18811 run_test 300g "check default striped directory for normal directory"
18812
18813 test_300h() {
18814         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18815         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18816                 skip "Need MDS version at least 2.7.55"
18817
18818         local dir
18819         local stripe_count
18820
18821         mkdir $DIR/$tdir
18822         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18823                 error "set striped dir error"
18824
18825         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
18826         test_300_check_default_striped_dir striped_dir 1 0
18827         test_300_check_default_striped_dir striped_dir 2 1
18828         test_300_check_default_striped_dir striped_dir 2 -1
18829
18830         #delete default stripe information
18831         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
18832                 error "set default stripe on striped dir error"
18833
18834         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
18835         for dir in $(find $DIR/$tdir/striped_dir/*); do
18836                 stripe_count=$($LFS getdirstripe -c $dir)
18837                 [ $stripe_count -eq 0 ] ||
18838                         error "expect 1 get $stripe_count for $dir"
18839         done
18840 }
18841 run_test 300h "check default striped directory for striped directory"
18842
18843 test_300i() {
18844         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18845         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18846         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18847                 skip "Need MDS version at least 2.7.55"
18848
18849         local stripe_count
18850         local file
18851
18852         mkdir $DIR/$tdir
18853
18854         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18855                 error "set striped dir error"
18856
18857         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18858                 error "create files under striped dir failed"
18859
18860         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
18861                 error "set striped hashdir error"
18862
18863         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
18864                 error "create dir0 under hash dir failed"
18865         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
18866                 error "create dir1 under hash dir failed"
18867
18868         # unfortunately, we need to umount to clear dir layout cache for now
18869         # once we fully implement dir layout, we can drop this
18870         umount_client $MOUNT || error "umount failed"
18871         mount_client $MOUNT || error "mount failed"
18872
18873         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
18874         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
18875         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
18876
18877         #set the stripe to be unknown hash type
18878         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
18879         $LCTL set_param fail_loc=0x1901
18880         for ((i = 0; i < 10; i++)); do
18881                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
18882                         error "stat f-$i failed"
18883                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
18884         done
18885
18886         touch $DIR/$tdir/striped_dir/f0 &&
18887                 error "create under striped dir with unknown hash should fail"
18888
18889         $LCTL set_param fail_loc=0
18890
18891         umount_client $MOUNT || error "umount failed"
18892         mount_client $MOUNT || error "mount failed"
18893
18894         return 0
18895 }
18896 run_test 300i "client handle unknown hash type striped directory"
18897
18898 test_300j() {
18899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18900         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18901         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18902                 skip "Need MDS version at least 2.7.55"
18903
18904         local stripe_count
18905         local file
18906
18907         mkdir $DIR/$tdir
18908
18909         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
18910         $LCTL set_param fail_loc=0x1702
18911         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
18912                 error "set striped dir error"
18913
18914         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
18915                 error "create files under striped dir failed"
18916
18917         $LCTL set_param fail_loc=0
18918
18919         rm -rf $DIR/$tdir || error "unlink striped dir fails"
18920
18921         return 0
18922 }
18923 run_test 300j "test large update record"
18924
18925 test_300k() {
18926         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18927         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18928         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18929                 skip "Need MDS version at least 2.7.55"
18930
18931         # this test needs a huge transaction
18932         local kb
18933         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
18934         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
18935
18936         local stripe_count
18937         local file
18938
18939         mkdir $DIR/$tdir
18940
18941         #define OBD_FAIL_LARGE_STRIPE   0x1703
18942         $LCTL set_param fail_loc=0x1703
18943         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
18944                 error "set striped dir error"
18945         $LCTL set_param fail_loc=0
18946
18947         $LFS getdirstripe $DIR/$tdir/striped_dir ||
18948                 error "getstripeddir fails"
18949         rm -rf $DIR/$tdir/striped_dir ||
18950                 error "unlink striped dir fails"
18951
18952         return 0
18953 }
18954 run_test 300k "test large striped directory"
18955
18956 test_300l() {
18957         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18958         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18959         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18960                 skip "Need MDS version at least 2.7.55"
18961
18962         local stripe_index
18963
18964         test_mkdir -p $DIR/$tdir/striped_dir
18965         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
18966                         error "chown $RUNAS_ID failed"
18967         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
18968                 error "set default striped dir failed"
18969
18970         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
18971         $LCTL set_param fail_loc=0x80000158
18972         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
18973
18974         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
18975         [ $stripe_index -eq 1 ] ||
18976                 error "expect 1 get $stripe_index for $dir"
18977 }
18978 run_test 300l "non-root user to create dir under striped dir with stale layout"
18979
18980 test_300m() {
18981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18982         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
18983         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
18984                 skip "Need MDS version at least 2.7.55"
18985
18986         mkdir -p $DIR/$tdir/striped_dir
18987         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
18988                 error "set default stripes dir error"
18989
18990         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
18991
18992         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
18993         [ $stripe_count -eq 0 ] ||
18994                         error "expect 0 get $stripe_count for a"
18995
18996         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
18997                 error "set default stripes dir error"
18998
18999         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19000
19001         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19002         [ $stripe_count -eq 0 ] ||
19003                         error "expect 0 get $stripe_count for b"
19004
19005         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19006                 error "set default stripes dir error"
19007
19008         mkdir $DIR/$tdir/striped_dir/c &&
19009                 error "default stripe_index is invalid, mkdir c should fails"
19010
19011         rm -rf $DIR/$tdir || error "rmdir fails"
19012 }
19013 run_test 300m "setstriped directory on single MDT FS"
19014
19015 cleanup_300n() {
19016         local list=$(comma_list $(mdts_nodes))
19017
19018         trap 0
19019         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19020 }
19021
19022 test_300n() {
19023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19025         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19026                 skip "Need MDS version at least 2.7.55"
19027         remote_mds_nodsh && skip "remote MDS with nodsh"
19028
19029         local stripe_index
19030         local list=$(comma_list $(mdts_nodes))
19031
19032         trap cleanup_300n RETURN EXIT
19033         mkdir -p $DIR/$tdir
19034         chmod 777 $DIR/$tdir
19035         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19036                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19037                 error "create striped dir succeeds with gid=0"
19038
19039         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19040         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19041                 error "create striped dir fails with gid=-1"
19042
19043         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19044         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19045                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19046                 error "set default striped dir succeeds with gid=0"
19047
19048
19049         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19050         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19051                 error "set default striped dir fails with gid=-1"
19052
19053
19054         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19055         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19056                                         error "create test_dir fails"
19057         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19058                                         error "create test_dir1 fails"
19059         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19060                                         error "create test_dir2 fails"
19061         cleanup_300n
19062 }
19063 run_test 300n "non-root user to create dir under striped dir with default EA"
19064
19065 test_300o() {
19066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19067         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19068         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19069                 skip "Need MDS version at least 2.7.55"
19070
19071         local numfree1
19072         local numfree2
19073
19074         mkdir -p $DIR/$tdir
19075
19076         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19077         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19078         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19079                 skip "not enough free inodes $numfree1 $numfree2"
19080         fi
19081
19082         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19083         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19084         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19085                 skip "not enough free space $numfree1 $numfree2"
19086         fi
19087
19088         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19089                 error "setdirstripe fails"
19090
19091         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19092                 error "create dirs fails"
19093
19094         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19095         ls $DIR/$tdir/striped_dir > /dev/null ||
19096                 error "ls striped dir fails"
19097         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19098                 error "unlink big striped dir fails"
19099 }
19100 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19101
19102 test_300p() {
19103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19104         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19105         remote_mds_nodsh && skip "remote MDS with nodsh"
19106
19107         mkdir -p $DIR/$tdir
19108
19109         #define OBD_FAIL_OUT_ENOSPC     0x1704
19110         do_facet mds2 lctl set_param fail_loc=0x80001704
19111         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19112                  && error "create striped directory should fail"
19113
19114         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19115
19116         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19117         true
19118 }
19119 run_test 300p "create striped directory without space"
19120
19121 test_300q() {
19122         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19123         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19124
19125         local fd=$(free_fd)
19126         local cmd="exec $fd<$tdir"
19127         cd $DIR
19128         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19129         eval $cmd
19130         cmd="exec $fd<&-"
19131         trap "eval $cmd" EXIT
19132         cd $tdir || error "cd $tdir fails"
19133         rmdir  ../$tdir || error "rmdir $tdir fails"
19134         mkdir local_dir && error "create dir succeeds"
19135         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19136         eval $cmd
19137         return 0
19138 }
19139 run_test 300q "create remote directory under orphan directory"
19140
19141 test_300r() {
19142         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19143                 skip "Need MDS version at least 2.7.55" && return
19144         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19145
19146         mkdir $DIR/$tdir
19147
19148         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19149                 error "set striped dir error"
19150
19151         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19152                 error "getstripeddir fails"
19153
19154         local stripe_count
19155         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19156                       awk '/lmv_stripe_count:/ { print $2 }')
19157
19158         [ $MDSCOUNT -ne $stripe_count ] &&
19159                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19160
19161         rm -rf $DIR/$tdir/striped_dir ||
19162                 error "unlink striped dir fails"
19163 }
19164 run_test 300r "test -1 striped directory"
19165
19166 prepare_remote_file() {
19167         mkdir $DIR/$tdir/src_dir ||
19168                 error "create remote source failed"
19169
19170         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19171                  error "cp to remote source failed"
19172         touch $DIR/$tdir/src_dir/a
19173
19174         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19175                 error "create remote target dir failed"
19176
19177         touch $DIR/$tdir/tgt_dir/b
19178
19179         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19180                 error "rename dir cross MDT failed!"
19181
19182         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19183                 error "src_child still exists after rename"
19184
19185         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19186                 error "missing file(a) after rename"
19187
19188         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19189                 error "diff after rename"
19190 }
19191
19192 test_310a() {
19193         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19195
19196         local remote_file=$DIR/$tdir/tgt_dir/b
19197
19198         mkdir -p $DIR/$tdir
19199
19200         prepare_remote_file || error "prepare remote file failed"
19201
19202         #open-unlink file
19203         $OPENUNLINK $remote_file $remote_file ||
19204                 error "openunlink $remote_file failed"
19205         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19206 }
19207 run_test 310a "open unlink remote file"
19208
19209 test_310b() {
19210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19212
19213         local remote_file=$DIR/$tdir/tgt_dir/b
19214
19215         mkdir -p $DIR/$tdir
19216
19217         prepare_remote_file || error "prepare remote file failed"
19218
19219         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19220         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19221         $CHECKSTAT -t file $remote_file || error "check file failed"
19222 }
19223 run_test 310b "unlink remote file with multiple links while open"
19224
19225 test_310c() {
19226         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19227         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19228
19229         local remote_file=$DIR/$tdir/tgt_dir/b
19230
19231         mkdir -p $DIR/$tdir
19232
19233         prepare_remote_file || error "prepare remote file failed"
19234
19235         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19236         multiop_bg_pause $remote_file O_uc ||
19237                         error "mulitop failed for remote file"
19238         MULTIPID=$!
19239         $MULTIOP $DIR/$tfile Ouc
19240         kill -USR1 $MULTIPID
19241         wait $MULTIPID
19242 }
19243 run_test 310c "open-unlink remote file with multiple links"
19244
19245 #LU-4825
19246 test_311() {
19247         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19248         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19249         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19250                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19251         remote_mds_nodsh && skip "remote MDS with nodsh"
19252
19253         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19254         local mdts=$(comma_list $(mdts_nodes))
19255
19256         mkdir -p $DIR/$tdir
19257         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19258         createmany -o $DIR/$tdir/$tfile. 1000
19259
19260         # statfs data is not real time, let's just calculate it
19261         old_iused=$((old_iused + 1000))
19262
19263         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19264                         osp.*OST0000*MDT0000.create_count")
19265         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19266                                 osp.*OST0000*MDT0000.max_create_count")
19267         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19268
19269         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19270         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19271         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19272
19273         unlinkmany $DIR/$tdir/$tfile. 1000
19274
19275         do_nodes $mdts "$LCTL set_param -n \
19276                         osp.*OST0000*.max_create_count=$max_count"
19277         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19278                 do_nodes $mdts "$LCTL set_param -n \
19279                                 osp.*OST0000*.create_count=$count"
19280         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19281                         grep "=0" && error "create_count is zero"
19282
19283         local new_iused
19284         for i in $(seq 120); do
19285                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19286                 # system may be too busy to destroy all objs in time, use
19287                 # a somewhat small value to not fail autotest
19288                 [ $((old_iused - new_iused)) -gt 400 ] && break
19289                 sleep 1
19290         done
19291
19292         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19293         [ $((old_iused - new_iused)) -gt 400 ] ||
19294                 error "objs not destroyed after unlink"
19295 }
19296 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19297
19298 zfs_oid_to_objid()
19299 {
19300         local ost=$1
19301         local objid=$2
19302
19303         local vdevdir=$(dirname $(facet_vdevice $ost))
19304         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19305         local zfs_zapid=$(do_facet $ost $cmd |
19306                           grep -w "/O/0/d$((objid%32))" -C 5 |
19307                           awk '/Object/{getline; print $1}')
19308         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19309                           awk "/$objid = /"'{printf $3}')
19310
19311         echo $zfs_objid
19312 }
19313
19314 zfs_object_blksz() {
19315         local ost=$1
19316         local objid=$2
19317
19318         local vdevdir=$(dirname $(facet_vdevice $ost))
19319         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19320         local blksz=$(do_facet $ost $cmd $objid |
19321                       awk '/dblk/{getline; printf $4}')
19322
19323         case "${blksz: -1}" in
19324                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19325                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19326                 *) ;;
19327         esac
19328
19329         echo $blksz
19330 }
19331
19332 test_312() { # LU-4856
19333         remote_ost_nodsh && skip "remote OST with nodsh"
19334         [ "$ost1_FSTYPE" = "zfs" ] ||
19335                 skip_env "the test only applies to zfs"
19336
19337         local max_blksz=$(do_facet ost1 \
19338                           $ZFS get -p recordsize $(facet_device ost1) |
19339                           awk '!/VALUE/{print $3}')
19340
19341         # to make life a little bit easier
19342         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19343         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19344
19345         local tf=$DIR/$tdir/$tfile
19346         touch $tf
19347         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19348
19349         # Get ZFS object id
19350         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19351         # block size change by sequential overwrite
19352         local bs
19353
19354         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19355                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19356
19357                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19358                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19359         done
19360         rm -f $tf
19361
19362         # block size change by sequential append write
19363         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19364         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19365         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19366         local count
19367
19368         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19369                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19370                         oflag=sync conv=notrunc
19371
19372                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19373                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19374                         error "blksz error, actual $blksz, " \
19375                                 "expected: 2 * $count * $PAGE_SIZE"
19376         done
19377         rm -f $tf
19378
19379         # random write
19380         touch $tf
19381         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19382         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19383
19384         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19385         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19386         [ $blksz -eq $PAGE_SIZE ] ||
19387                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19388
19389         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19390         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19391         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19392
19393         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19394         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19395         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19396 }
19397 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19398
19399 test_313() {
19400         remote_ost_nodsh && skip "remote OST with nodsh"
19401
19402         local file=$DIR/$tfile
19403
19404         rm -f $file
19405         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19406
19407         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19408         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19409         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19410                 error "write should failed"
19411         do_facet ost1 "$LCTL set_param fail_loc=0"
19412         rm -f $file
19413 }
19414 run_test 313 "io should fail after last_rcvd update fail"
19415
19416 test_314() {
19417         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19418
19419         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19420         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19421         rm -f $DIR/$tfile
19422         wait_delete_completed
19423         do_facet ost1 "$LCTL set_param fail_loc=0"
19424 }
19425 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19426
19427 test_315() { # LU-618
19428         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19429
19430         local file=$DIR/$tfile
19431         rm -f $file
19432
19433         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19434                 error "multiop file write failed"
19435         $MULTIOP $file oO_RDONLY:r4063232_c &
19436         PID=$!
19437
19438         sleep 2
19439
19440         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19441         kill -USR1 $PID
19442
19443         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19444         rm -f $file
19445 }
19446 run_test 315 "read should be accounted"
19447
19448 test_316() {
19449         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19450         large_xattr_enabled || skip_env "ea_inode feature disabled"
19451
19452         rm -rf $DIR/$tdir/d
19453         mkdir -p $DIR/$tdir/d
19454         chown nobody $DIR/$tdir/d
19455         touch $DIR/$tdir/d/file
19456
19457         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19458 }
19459 run_test 316 "lfs mv"
19460
19461 test_317() {
19462         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19463                 skip "Need MDS version at least 2.11.53"
19464         if [ "$ost1_FSTYPE" == "zfs" ]; then
19465                 skip "LU-10370: no implementation for ZFS"
19466         fi
19467
19468         local trunc_sz
19469         local grant_blk_size
19470
19471         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19472                         awk '/grant_block_size:/ { print $2; exit; }')
19473         #
19474         # Create File of size 5M. Truncate it to below size's and verify
19475         # blocks count.
19476         #
19477         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19478                 error "Create file $DIR/$tfile failed"
19479         stack_trap "rm -f $DIR/$tfile" EXIT
19480
19481         for trunc_sz in 2097152 4097 4000 509 0; do
19482                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19483                         error "truncate $tfile to $trunc_sz failed"
19484                 local sz=$(stat --format=%s $DIR/$tfile)
19485                 local blk=$(stat --format=%b $DIR/$tfile)
19486                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19487                                      grant_blk_size) * 8))
19488
19489                 if [[ $blk -ne $trunc_blk ]]; then
19490                         $(which stat) $DIR/$tfile
19491                         error "Expected Block $trunc_blk got $blk for $tfile"
19492                 fi
19493
19494                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19495                         error "Expected Size $trunc_sz got $sz for $tfile"
19496         done
19497
19498         #
19499         # sparse file test
19500         # Create file with a hole and write actual two blocks. Block count
19501         # must be 16.
19502         #
19503         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19504                 conv=fsync || error "Create file : $DIR/$tfile"
19505
19506         # Calculate the final truncate size.
19507         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19508
19509         #
19510         # truncate to size $trunc_sz bytes. Strip the last block
19511         # The block count must drop to 8
19512         #
19513         $TRUNCATE $DIR/$tfile $trunc_sz ||
19514                 error "truncate $tfile to $trunc_sz failed"
19515
19516         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19517         sz=$(stat --format=%s $DIR/$tfile)
19518         blk=$(stat --format=%b $DIR/$tfile)
19519
19520         if [[ $blk -ne $trunc_bsz ]]; then
19521                 $(which stat) $DIR/$tfile
19522                 error "Expected Block $trunc_bsz got $blk for $tfile"
19523         fi
19524
19525         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19526                 error "Expected Size $trunc_sz got $sz for $tfile"
19527 }
19528 run_test 317 "Verify blocks get correctly update after truncate"
19529
19530 test_318() {
19531         local old_max_active=$($LCTL get_param -n \
19532                             llite.*.max_read_ahead_async_active 2>/dev/null)
19533
19534         $LCTL set_param llite.*.max_read_ahead_async_active=256
19535         local max_active=$($LCTL get_param -n \
19536                            llite.*.max_read_ahead_async_active 2>/dev/null)
19537         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19538
19539         # currently reset to 0 is unsupported, leave it 512 for now.
19540         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19541                 error "set max_read_ahead_async_active should fail"
19542
19543         $LCTL set_param llite.*.max_read_ahead_async_active=512
19544         max_active=$($LCTL get_param -n \
19545                      llite.*.max_read_ahead_async_active 2>/dev/null)
19546         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19547
19548         # restore @max_active
19549         [ $old_max_active -ne 0 ] && $LCTL set_param \
19550                 llite.*.max_read_ahead_async_active=$old_max_active
19551
19552         local old_threshold=$($LCTL get_param -n \
19553                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19554         local max_per_file_mb=$($LCTL get_param -n \
19555                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19556
19557         local invalid=$(($max_per_file_mb + 1))
19558         $LCTL set_param \
19559                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19560                         && error "set $invalid should fail"
19561
19562         local valid=$(($invalid - 1))
19563         $LCTL set_param \
19564                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19565                         error "set $valid should succeed"
19566         local threshold=$($LCTL get_param -n \
19567                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19568         [ $threshold -eq $valid ] || error \
19569                 "expect threshold $valid got $threshold"
19570         $LCTL set_param \
19571                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19572 }
19573 run_test 318 "Verify async readahead tunables"
19574
19575 test_319() {
19576         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19577
19578         local before=$(date +%s)
19579         local evict
19580         local mdir=$DIR/$tdir
19581         local file=$mdir/xxx
19582
19583         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19584         touch $file
19585
19586 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19587         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19588         $LFS mv -m1 $file &
19589
19590         sleep 1
19591         dd if=$file of=/dev/null
19592         wait
19593         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19594           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19595
19596         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19597 }
19598 run_test 319 "lost lease lock on migrate error"
19599
19600 test_fake_rw() {
19601         local read_write=$1
19602         if [ "$read_write" = "write" ]; then
19603                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
19604         elif [ "$read_write" = "read" ]; then
19605                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
19606         else
19607                 error "argument error"
19608         fi
19609
19610         # turn off debug for performance testing
19611         local saved_debug=$($LCTL get_param -n debug)
19612         $LCTL set_param debug=0
19613
19614         $LFS setstripe -c 1 -i 0 $DIR/$tfile
19615
19616         # get ost1 size - lustre-OST0000
19617         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
19618         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
19619         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
19620
19621         if [ "$read_write" = "read" ]; then
19622                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
19623         fi
19624
19625         local start_time=$(date +%s.%N)
19626         $dd_cmd bs=1M count=$blocks oflag=sync ||
19627                 error "real dd $read_write error"
19628         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
19629
19630         if [ "$read_write" = "write" ]; then
19631                 rm -f $DIR/$tfile
19632         fi
19633
19634         # define OBD_FAIL_OST_FAKE_RW           0x238
19635         do_facet ost1 $LCTL set_param fail_loc=0x238
19636
19637         local start_time=$(date +%s.%N)
19638         $dd_cmd bs=1M count=$blocks oflag=sync ||
19639                 error "fake dd $read_write error"
19640         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
19641
19642         if [ "$read_write" = "write" ]; then
19643                 # verify file size
19644                 cancel_lru_locks osc
19645                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
19646                         error "$tfile size not $blocks MB"
19647         fi
19648         do_facet ost1 $LCTL set_param fail_loc=0
19649
19650         echo "fake $read_write $duration_fake vs. normal $read_write" \
19651                 "$duration in seconds"
19652         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
19653                 error_not_in_vm "fake write is slower"
19654
19655         $LCTL set_param -n debug="$saved_debug"
19656         rm -f $DIR/$tfile
19657 }
19658 test_399a() { # LU-7655 for OST fake write
19659         remote_ost_nodsh && skip "remote OST with nodsh"
19660
19661         test_fake_rw write
19662 }
19663 run_test 399a "fake write should not be slower than normal write"
19664
19665 test_399b() { # LU-8726 for OST fake read
19666         remote_ost_nodsh && skip "remote OST with nodsh"
19667         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
19668                 skip_env "ldiskfs only test"
19669         fi
19670
19671         test_fake_rw read
19672 }
19673 run_test 399b "fake read should not be slower than normal read"
19674
19675 test_400a() { # LU-1606, was conf-sanity test_74
19676         if ! which $CC > /dev/null 2>&1; then
19677                 skip_env "$CC is not installed"
19678         fi
19679
19680         local extra_flags=''
19681         local out=$TMP/$tfile
19682         local prefix=/usr/include/lustre
19683         local prog
19684
19685         if ! [[ -d $prefix ]]; then
19686                 # Assume we're running in tree and fixup the include path.
19687                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
19688                 extra_flags+=" -L$LUSTRE/utils/.lib"
19689         fi
19690
19691         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
19692                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
19693                         error "client api broken"
19694         done
19695         rm -f $out
19696 }
19697 run_test 400a "Lustre client api program can compile and link"
19698
19699 test_400b() { # LU-1606, LU-5011
19700         local header
19701         local out=$TMP/$tfile
19702         local prefix=/usr/include/linux/lustre
19703
19704         # We use a hard coded prefix so that this test will not fail
19705         # when run in tree. There are headers in lustre/include/lustre/
19706         # that are not packaged (like lustre_idl.h) and have more
19707         # complicated include dependencies (like config.h and lnet/types.h).
19708         # Since this test about correct packaging we just skip them when
19709         # they don't exist (see below) rather than try to fixup cppflags.
19710
19711         if ! which $CC > /dev/null 2>&1; then
19712                 skip_env "$CC is not installed"
19713         fi
19714
19715         for header in $prefix/*.h; do
19716                 if ! [[ -f "$header" ]]; then
19717                         continue
19718                 fi
19719
19720                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
19721                         continue # lustre_ioctl.h is internal header
19722                 fi
19723
19724                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
19725                         error "cannot compile '$header'"
19726         done
19727         rm -f $out
19728 }
19729 run_test 400b "packaged headers can be compiled"
19730
19731 test_401a() { #LU-7437
19732         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
19733         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
19734
19735         #count the number of parameters by "list_param -R"
19736         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
19737         #count the number of parameters by listing proc files
19738         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
19739         echo "proc_dirs='$proc_dirs'"
19740         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
19741         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
19742                       sort -u | wc -l)
19743
19744         [ $params -eq $procs ] ||
19745                 error "found $params parameters vs. $procs proc files"
19746
19747         # test the list_param -D option only returns directories
19748         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
19749         #count the number of parameters by listing proc directories
19750         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
19751                 sort -u | wc -l)
19752
19753         [ $params -eq $procs ] ||
19754                 error "found $params parameters vs. $procs proc files"
19755 }
19756 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
19757
19758 test_401b() {
19759         local save=$($LCTL get_param -n jobid_var)
19760         local tmp=testing
19761
19762         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
19763                 error "no error returned when setting bad parameters"
19764
19765         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
19766         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
19767
19768         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
19769         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
19770         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
19771 }
19772 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
19773
19774 test_401c() {
19775         local jobid_var_old=$($LCTL get_param -n jobid_var)
19776         local jobid_var_new
19777
19778         $LCTL set_param jobid_var= &&
19779                 error "no error returned for 'set_param a='"
19780
19781         jobid_var_new=$($LCTL get_param -n jobid_var)
19782         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19783                 error "jobid_var was changed by setting without value"
19784
19785         $LCTL set_param jobid_var &&
19786                 error "no error returned for 'set_param a'"
19787
19788         jobid_var_new=$($LCTL get_param -n jobid_var)
19789         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
19790                 error "jobid_var was changed by setting without value"
19791 }
19792 run_test 401c "Verify 'lctl set_param' without value fails in either format."
19793
19794 test_401d() {
19795         local jobid_var_old=$($LCTL get_param -n jobid_var)
19796         local jobid_var_new
19797         local new_value="foo=bar"
19798
19799         $LCTL set_param jobid_var=$new_value ||
19800                 error "'set_param a=b' did not accept a value containing '='"
19801
19802         jobid_var_new=$($LCTL get_param -n jobid_var)
19803         [[ "$jobid_var_new" == "$new_value" ]] ||
19804                 error "'set_param a=b' failed on a value containing '='"
19805
19806         # Reset the jobid_var to test the other format
19807         $LCTL set_param jobid_var=$jobid_var_old
19808         jobid_var_new=$($LCTL get_param -n jobid_var)
19809         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19810                 error "failed to reset jobid_var"
19811
19812         $LCTL set_param jobid_var $new_value ||
19813                 error "'set_param a b' did not accept a value containing '='"
19814
19815         jobid_var_new=$($LCTL get_param -n jobid_var)
19816         [[ "$jobid_var_new" == "$new_value" ]] ||
19817                 error "'set_param a b' failed on a value containing '='"
19818
19819         $LCTL set_param jobid_var $jobid_var_old
19820         jobid_var_new=$($LCTL get_param -n jobid_var)
19821         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
19822                 error "failed to reset jobid_var"
19823 }
19824 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
19825
19826 test_402() {
19827         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
19828         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
19829                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
19830         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
19831                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
19832                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
19833         remote_mds_nodsh && skip "remote MDS with nodsh"
19834
19835         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
19836 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
19837         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
19838         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
19839                 echo "Touch failed - OK"
19840 }
19841 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
19842
19843 test_403() {
19844         local file1=$DIR/$tfile.1
19845         local file2=$DIR/$tfile.2
19846         local tfile=$TMP/$tfile
19847
19848         rm -f $file1 $file2 $tfile
19849
19850         touch $file1
19851         ln $file1 $file2
19852
19853         # 30 sec OBD_TIMEOUT in ll_getattr()
19854         # right before populating st_nlink
19855         $LCTL set_param fail_loc=0x80001409
19856         stat -c %h $file1 > $tfile &
19857
19858         # create an alias, drop all locks and reclaim the dentry
19859         < $file2
19860         cancel_lru_locks mdc
19861         cancel_lru_locks osc
19862         sysctl -w vm.drop_caches=2
19863
19864         wait
19865
19866         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
19867
19868         rm -f $tfile $file1 $file2
19869 }
19870 run_test 403 "i_nlink should not drop to zero due to aliasing"
19871
19872 test_404() { # LU-6601
19873         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
19874                 skip "Need server version newer than 2.8.52"
19875         remote_mds_nodsh && skip "remote MDS with nodsh"
19876
19877         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
19878                 awk '/osp .*-osc-MDT/ { print $4}')
19879
19880         local osp
19881         for osp in $mosps; do
19882                 echo "Deactivate: " $osp
19883                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
19884                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19885                         awk -vp=$osp '$4 == p { print $2 }')
19886                 [ $stat = IN ] || {
19887                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19888                         error "deactivate error"
19889                 }
19890                 echo "Activate: " $osp
19891                 do_facet $SINGLEMDS $LCTL --device %$osp activate
19892                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
19893                         awk -vp=$osp '$4 == p { print $2 }')
19894                 [ $stat = UP ] || {
19895                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
19896                         error "activate error"
19897                 }
19898         done
19899 }
19900 run_test 404 "validate manual {de}activated works properly for OSPs"
19901
19902 test_405() {
19903         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
19904         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
19905                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
19906                         skip "Layout swap lock is not supported"
19907
19908         check_swap_layouts_support
19909
19910         test_mkdir $DIR/$tdir
19911         swap_lock_test -d $DIR/$tdir ||
19912                 error "One layout swap locked test failed"
19913 }
19914 run_test 405 "Various layout swap lock tests"
19915
19916 test_406() {
19917         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19918         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
19919         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
19920         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19921         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
19922                 skip "Need MDS version at least 2.8.50"
19923
19924         local def_stripe_size=$($LFS getstripe -S $MOUNT)
19925         local test_pool=$TESTNAME
19926
19927         if ! combined_mgs_mds ; then
19928                 mount_mgs_client
19929         fi
19930         pool_add $test_pool || error "pool_add failed"
19931         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
19932                 error "pool_add_targets failed"
19933
19934         save_layout_restore_at_exit $MOUNT
19935
19936         # parent set default stripe count only, child will stripe from both
19937         # parent and fs default
19938         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
19939                 error "setstripe $MOUNT failed"
19940         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
19941         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
19942         for i in $(seq 10); do
19943                 local f=$DIR/$tdir/$tfile.$i
19944                 touch $f || error "touch failed"
19945                 local count=$($LFS getstripe -c $f)
19946                 [ $count -eq $OSTCOUNT ] ||
19947                         error "$f stripe count $count != $OSTCOUNT"
19948                 local offset=$($LFS getstripe -i $f)
19949                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
19950                 local size=$($LFS getstripe -S $f)
19951                 [ $size -eq $((def_stripe_size * 2)) ] ||
19952                         error "$f stripe size $size != $((def_stripe_size * 2))"
19953                 local pool=$($LFS getstripe -p $f)
19954                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
19955         done
19956
19957         # change fs default striping, delete parent default striping, now child
19958         # will stripe from new fs default striping only
19959         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
19960                 error "change $MOUNT default stripe failed"
19961         $LFS setstripe -c 0 $DIR/$tdir ||
19962                 error "delete $tdir default stripe failed"
19963         for i in $(seq 11 20); do
19964                 local f=$DIR/$tdir/$tfile.$i
19965                 touch $f || error "touch $f failed"
19966                 local count=$($LFS getstripe -c $f)
19967                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
19968                 local offset=$($LFS getstripe -i $f)
19969                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
19970                 local size=$($LFS getstripe -S $f)
19971                 [ $size -eq $def_stripe_size ] ||
19972                         error "$f stripe size $size != $def_stripe_size"
19973                 local pool=$($LFS getstripe -p $f)
19974                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
19975         done
19976
19977         unlinkmany $DIR/$tdir/$tfile. 1 20
19978
19979         local f=$DIR/$tdir/$tfile
19980         pool_remove_all_targets $test_pool $f
19981         pool_remove $test_pool $f
19982
19983         if ! combined_mgs_mds ; then
19984                 umount_mgs_client
19985         fi
19986 }
19987 run_test 406 "DNE support fs default striping"
19988
19989 test_407() {
19990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19991         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
19992                 skip "Need MDS version at least 2.8.55"
19993         remote_mds_nodsh && skip "remote MDS with nodsh"
19994
19995         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
19996                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
19997         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
19998                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
19999         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20000
20001         #define OBD_FAIL_DT_TXN_STOP    0x2019
20002         for idx in $(seq $MDSCOUNT); do
20003                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20004         done
20005         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20006         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20007                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20008         true
20009 }
20010 run_test 407 "transaction fail should cause operation fail"
20011
20012 test_408() {
20013         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20014
20015         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20016         lctl set_param fail_loc=0x8000040a
20017         # let ll_prepare_partial_page() fail
20018         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20019
20020         rm -f $DIR/$tfile
20021
20022         # create at least 100 unused inodes so that
20023         # shrink_icache_memory(0) should not return 0
20024         touch $DIR/$tfile-{0..100}
20025         rm -f $DIR/$tfile-{0..100}
20026         sync
20027
20028         echo 2 > /proc/sys/vm/drop_caches
20029 }
20030 run_test 408 "drop_caches should not hang due to page leaks"
20031
20032 test_409()
20033 {
20034         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20035
20036         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20037         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20038         touch $DIR/$tdir/guard || error "(2) Fail to create"
20039
20040         local PREFIX=$(str_repeat 'A' 128)
20041         echo "Create 1K hard links start at $(date)"
20042         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20043                 error "(3) Fail to hard link"
20044
20045         echo "Links count should be right although linkEA overflow"
20046         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20047         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20048         [ $linkcount -eq 1001 ] ||
20049                 error "(5) Unexpected hard links count: $linkcount"
20050
20051         echo "List all links start at $(date)"
20052         ls -l $DIR/$tdir/foo > /dev/null ||
20053                 error "(6) Fail to list $DIR/$tdir/foo"
20054
20055         echo "Unlink hard links start at $(date)"
20056         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20057                 error "(7) Fail to unlink"
20058         echo "Unlink hard links finished at $(date)"
20059 }
20060 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20061
20062 test_410()
20063 {
20064         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20065                 skip "Need client version at least 2.9.59"
20066
20067         # Create a file, and stat it from the kernel
20068         local testfile=$DIR/$tfile
20069         touch $testfile
20070
20071         local run_id=$RANDOM
20072         local my_ino=$(stat --format "%i" $testfile)
20073
20074         # Try to insert the module. This will always fail as the
20075         # module is designed to not be inserted.
20076         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20077             &> /dev/null
20078
20079         # Anything but success is a test failure
20080         dmesg | grep -q \
20081             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20082             error "no inode match"
20083 }
20084 run_test 410 "Test inode number returned from kernel thread"
20085
20086 cleanup_test411_cgroup() {
20087         trap 0
20088         rmdir "$1"
20089 }
20090
20091 test_411() {
20092         local cg_basedir=/sys/fs/cgroup/memory
20093         # LU-9966
20094         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20095                 skip "no setup for cgroup"
20096
20097         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20098                 error "test file creation failed"
20099         cancel_lru_locks osc
20100
20101         # Create a very small memory cgroup to force a slab allocation error
20102         local cgdir=$cg_basedir/osc_slab_alloc
20103         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20104         trap "cleanup_test411_cgroup $cgdir" EXIT
20105         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20106         echo 1M > $cgdir/memory.limit_in_bytes
20107
20108         # Should not LBUG, just be killed by oom-killer
20109         # dd will return 0 even allocation failure in some environment.
20110         # So don't check return value
20111         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20112         cleanup_test411_cgroup $cgdir
20113
20114         return 0
20115 }
20116 run_test 411 "Slab allocation error with cgroup does not LBUG"
20117
20118 test_412() {
20119         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20120         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20121                 skip "Need server version at least 2.10.55"
20122         fi
20123
20124         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20125                 error "mkdir failed"
20126         $LFS getdirstripe $DIR/$tdir
20127         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20128         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20129                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20130         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20131         [ $stripe_count -eq 2 ] ||
20132                 error "expect 2 get $stripe_count"
20133 }
20134 run_test 412 "mkdir on specific MDTs"
20135
20136 test_413a() {
20137         [ $MDSCOUNT -lt 2 ] &&
20138                 skip "We need at least 2 MDTs for this test"
20139
20140         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20141                 skip "Need server version at least 2.10.55"
20142         fi
20143
20144         mkdir $DIR/$tdir || error "mkdir failed"
20145
20146         # find MDT that is the most full
20147         local max=$($LFS df | grep MDT |
20148                 awk 'BEGIN { a=0 }
20149                         { sub("%", "", $5)
20150                           if (0+$5 >= a)
20151                           {
20152                                 a = $5
20153                                 b = $6
20154                           }
20155                         }
20156                      END { split(b, c, ":")
20157                            sub("]", "", c[2])
20158                            print c[2]
20159                          }')
20160
20161         for i in $(seq $((MDSCOUNT - 1))); do
20162                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20163                         error "mkdir d$i failed"
20164                 $LFS getdirstripe $DIR/$tdir/d$i
20165                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20166                 [ $stripe_index -ne $max ] ||
20167                         error "don't expect $max"
20168         done
20169 }
20170 run_test 413a "mkdir on less full MDTs"
20171
20172 test_413b() {
20173         [ $MDSCOUNT -lt 2 ] &&
20174                 skip "We need at least 2 MDTs for this test"
20175
20176         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20177                 skip "Need server version at least 2.12.52"
20178
20179         mkdir $DIR/$tdir || error "mkdir failed"
20180         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20181                 error "setdirstripe failed"
20182
20183         local qos_prio_free
20184         local qos_threshold_rr
20185         local count
20186
20187         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20188         qos_prio_free=${qos_prio_free%%%}
20189         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20190         qos_threshold_rr=${qos_threshold_rr%%%}
20191         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20192
20193         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20194         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20195                 EXIT
20196         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20197
20198         echo "mkdir with roundrobin"
20199
20200         $LCTL set_param lmv.*.qos_threshold_rr=100
20201         for i in $(seq $((100 * MDSCOUNT))); do
20202                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20203         done
20204         for i in $(seq $MDSCOUNT); do
20205                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20206                         wc -w)
20207                 echo "$count directories created on MDT$((i - 1))"
20208                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20209         done
20210
20211         rm -rf $DIR/$tdir/*
20212
20213         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20214         # Shorten statfs result age, so that it can be updated in time
20215         $LCTL set_param lmv.*.qos_maxage=1
20216         sleep_maxage
20217
20218         local ffree
20219         local max
20220         local min
20221         local max_index
20222         local min_index
20223
20224         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20225         echo "MDT filesfree available: ${ffree[@]}"
20226         max=${ffree[0]}
20227         min=${ffree[0]}
20228         max_index=0
20229         min_index=0
20230         for ((i = 0; i < ${#ffree[@]}; i++)); do
20231                 if [[ ${ffree[i]} -gt $max ]]; then
20232                         max=${ffree[i]}
20233                         max_index=$i
20234                 fi
20235                 if [[ ${ffree[i]} -lt $min ]]; then
20236                         min=${ffree[i]}
20237                         min_index=$i
20238                 fi
20239         done
20240         echo "Min free files: MDT$min_index: $min"
20241         echo "Max free files: MDT$max_index: $max"
20242
20243         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20244         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20245
20246         # Check if we need to generate uneven MDTs
20247         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20248         local threshold=10
20249         local diff=$((max - min))
20250         local diff2=$((diff * 100 / min))
20251
20252         echo -n "Check for uneven MDTs: "
20253         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20254
20255         if [ $diff2 -gt $threshold ]; then
20256                 echo "ok"
20257                 echo "Don't need to fill MDT$min_index"
20258         else
20259                 # generate uneven MDTs, create till 25% diff
20260                 echo "no"
20261                 diff2=$((threshold - diff2))
20262                 diff=$((min * diff2 / 100))
20263                 # 50 sec per 10000 files in vm
20264                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20265                         skip "$diff files to create"
20266                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20267                 local i
20268                 local value="$(generate_string 1024)"
20269                 for i in $(seq $diff); do
20270                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20271                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20272                                 error "create f$i failed"
20273                         setfattr -n user.413b -v $value \
20274                                 $DIR/$tdir-MDT$min_index/f$i ||
20275                                 error "setfattr f$i failed"
20276                 done
20277         fi
20278
20279         min=$((100 *MDSCOUNT))
20280         max=0
20281
20282         echo "mkdir with balanced space usage"
20283         $LCTL set_param lmv.*.qos_prio_free=100
20284         for i in $(seq $((100 * MDSCOUNT))); do
20285                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20286         done
20287         for i in $(seq $MDSCOUNT); do
20288                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20289                         wc -w)
20290                 echo "$count directories created on MDT$((i - 1))"
20291                 [ $min -gt $count ] && min=$count
20292                 [ $max -lt $count ] && max=$count
20293         done
20294         [ $((max - min)) -gt $MDSCOUNT ] ||
20295                 error "subdirs shouldn't be evenly distributed"
20296
20297         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20298
20299         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20300         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20301         true
20302 }
20303 run_test 413b "mkdir with balanced space usage"
20304
20305 test_414() {
20306 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20307         $LCTL set_param fail_loc=0x80000521
20308         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20309         rm -f $DIR/$tfile
20310 }
20311 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20312
20313 test_415() {
20314         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20315         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20316                 skip "Need server version at least 2.11.52"
20317
20318         # LU-11102
20319         local total
20320         local setattr_pid
20321         local start_time
20322         local end_time
20323         local duration
20324
20325         total=500
20326         # this test may be slow on ZFS
20327         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20328
20329         # though this test is designed for striped directory, let's test normal
20330         # directory too since lock is always saved as CoS lock.
20331         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20332         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20333
20334         (
20335                 while true; do
20336                         touch $DIR/$tdir
20337                 done
20338         ) &
20339         setattr_pid=$!
20340
20341         start_time=$(date +%s)
20342         for i in $(seq $total); do
20343                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20344                         > /dev/null
20345         done
20346         end_time=$(date +%s)
20347         duration=$((end_time - start_time))
20348
20349         kill -9 $setattr_pid
20350
20351         echo "rename $total files took $duration sec"
20352         [ $duration -lt 100 ] || error "rename took $duration sec"
20353 }
20354 run_test 415 "lock revoke is not missing"
20355
20356 test_416() {
20357         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20358                 skip "Need server version at least 2.11.55"
20359
20360         # define OBD_FAIL_OSD_TXN_START    0x19a
20361         do_facet mds1 lctl set_param fail_loc=0x19a
20362
20363         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20364
20365         true
20366 }
20367 run_test 416 "transaction start failure won't cause system hung"
20368
20369 cleanup_417() {
20370         trap 0
20371         do_nodes $(comma_list $(mdts_nodes)) \
20372                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20373         do_nodes $(comma_list $(mdts_nodes)) \
20374                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20375         do_nodes $(comma_list $(mdts_nodes)) \
20376                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20377 }
20378
20379 test_417() {
20380         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20381         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20382                 skip "Need MDS version at least 2.11.56"
20383
20384         trap cleanup_417 RETURN EXIT
20385
20386         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20387         do_nodes $(comma_list $(mdts_nodes)) \
20388                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20389         $LFS migrate -m 0 $DIR/$tdir.1 &&
20390                 error "migrate dir $tdir.1 should fail"
20391
20392         do_nodes $(comma_list $(mdts_nodes)) \
20393                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20394         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20395                 error "create remote dir $tdir.2 should fail"
20396
20397         do_nodes $(comma_list $(mdts_nodes)) \
20398                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20399         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20400                 error "create striped dir $tdir.3 should fail"
20401         true
20402 }
20403 run_test 417 "disable remote dir, striped dir and dir migration"
20404
20405 # Checks that the outputs of df [-i] and lfs df [-i] match
20406 #
20407 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20408 check_lfs_df() {
20409         local dir=$2
20410         local inodes
20411         local df_out
20412         local lfs_df_out
20413         local count
20414         local passed=false
20415
20416         # blocks or inodes
20417         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20418
20419         for count in {1..100}; do
20420                 cancel_lru_locks
20421                 sync; sleep 0.2
20422
20423                 # read the lines of interest
20424                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20425                         error "df $inodes $dir | tail -n +2 failed"
20426                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20427                         error "lfs df $inodes $dir | grep summary: failed"
20428
20429                 # skip first substrings of each output as they are different
20430                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20431                 # compare the two outputs
20432                 passed=true
20433                 for i in {1..5}; do
20434                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20435                 done
20436                 $passed && break
20437         done
20438
20439         if ! $passed; then
20440                 df -P $inodes $dir
20441                 echo
20442                 lfs df $inodes $dir
20443                 error "df and lfs df $1 output mismatch: "      \
20444                       "df ${inodes}: ${df_out[*]}, "            \
20445                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20446         fi
20447 }
20448
20449 test_418() {
20450         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20451
20452         local dir=$DIR/$tdir
20453         local numfiles=$((RANDOM % 4096 + 2))
20454         local numblocks=$((RANDOM % 256 + 1))
20455
20456         wait_delete_completed
20457         test_mkdir $dir
20458
20459         # check block output
20460         check_lfs_df blocks $dir
20461         # check inode output
20462         check_lfs_df inodes $dir
20463
20464         # create a single file and retest
20465         echo "Creating a single file and testing"
20466         createmany -o $dir/$tfile- 1 &>/dev/null ||
20467                 error "creating 1 file in $dir failed"
20468         check_lfs_df blocks $dir
20469         check_lfs_df inodes $dir
20470
20471         # create a random number of files
20472         echo "Creating $((numfiles - 1)) files and testing"
20473         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20474                 error "creating $((numfiles - 1)) files in $dir failed"
20475
20476         # write a random number of blocks to the first test file
20477         echo "Writing $numblocks 4K blocks and testing"
20478         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20479                 count=$numblocks &>/dev/null ||
20480                 error "dd to $dir/${tfile}-0 failed"
20481
20482         # retest
20483         check_lfs_df blocks $dir
20484         check_lfs_df inodes $dir
20485
20486         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20487                 error "unlinking $numfiles files in $dir failed"
20488 }
20489 run_test 418 "df and lfs df outputs match"
20490
20491 test_419()
20492 {
20493         local dir=$DIR/$tdir
20494
20495         mkdir -p $dir
20496         touch $dir/file
20497
20498         cancel_lru_locks mdc
20499
20500         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20501         $LCTL set_param fail_loc=0x1410
20502         cat $dir/file
20503         $LCTL set_param fail_loc=0
20504         rm -rf $dir
20505 }
20506 run_test 419 "Verify open file by name doesn't crash kernel"
20507
20508 test_420()
20509 {
20510         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20511                 skip "Need MDS version at least 2.12.53"
20512
20513         local SAVE_UMASK=$(umask)
20514         local dir=$DIR/$tdir
20515         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20516
20517         mkdir -p $dir
20518         umask 0000
20519         mkdir -m03777 $dir/testdir
20520         ls -dn $dir/testdir
20521         # Need to remove trailing '.' when SELinux is enabled
20522         local dirperms=$(ls -dn $dir/testdir |
20523                          awk '{ sub(/\.$/, "", $1); print $1}')
20524         [ $dirperms == "drwxrwsrwt" ] ||
20525                 error "incorrect perms on $dir/testdir"
20526
20527         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20528                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20529         ls -n $dir/testdir/testfile
20530         local fileperms=$(ls -n $dir/testdir/testfile |
20531                           awk '{ sub(/\.$/, "", $1); print $1}')
20532         [ $fileperms == "-rwxr-xr-x" ] ||
20533                 error "incorrect perms on $dir/testdir/testfile"
20534
20535         umask $SAVE_UMASK
20536 }
20537 run_test 420 "clear SGID bit on non-directories for non-members"
20538
20539 test_421a() {
20540         local cnt
20541         local fid1
20542         local fid2
20543
20544         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20545                 skip "Need MDS version at least 2.12.54"
20546
20547         test_mkdir $DIR/$tdir
20548         createmany -o $DIR/$tdir/f 3
20549         cnt=$(ls -1 $DIR/$tdir | wc -l)
20550         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20551
20552         fid1=$(lfs path2fid $DIR/$tdir/f1)
20553         fid2=$(lfs path2fid $DIR/$tdir/f2)
20554         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
20555
20556         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
20557         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
20558
20559         cnt=$(ls -1 $DIR/$tdir | wc -l)
20560         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20561
20562         rm -f $DIR/$tdir/f3 || error "can't remove f3"
20563         createmany -o $DIR/$tdir/f 3
20564         cnt=$(ls -1 $DIR/$tdir | wc -l)
20565         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20566
20567         fid1=$(lfs path2fid $DIR/$tdir/f1)
20568         fid2=$(lfs path2fid $DIR/$tdir/f2)
20569         echo "remove using fsname $FSNAME"
20570         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
20571
20572         cnt=$(ls -1 $DIR/$tdir | wc -l)
20573         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20574 }
20575 run_test 421a "simple rm by fid"
20576
20577 test_421b() {
20578         local cnt
20579         local FID1
20580         local FID2
20581
20582         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20583                 skip "Need MDS version at least 2.12.54"
20584
20585         test_mkdir $DIR/$tdir
20586         createmany -o $DIR/$tdir/f 3
20587         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
20588         MULTIPID=$!
20589
20590         FID1=$(lfs path2fid $DIR/$tdir/f1)
20591         FID2=$(lfs path2fid $DIR/$tdir/f2)
20592         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
20593
20594         kill -USR1 $MULTIPID
20595         wait
20596
20597         cnt=$(ls $DIR/$tdir | wc -l)
20598         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
20599 }
20600 run_test 421b "rm by fid on open file"
20601
20602 test_421c() {
20603         local cnt
20604         local FIDS
20605
20606         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20607                 skip "Need MDS version at least 2.12.54"
20608
20609         test_mkdir $DIR/$tdir
20610         createmany -o $DIR/$tdir/f 3
20611         touch $DIR/$tdir/$tfile
20612         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
20613         cnt=$(ls -1 $DIR/$tdir | wc -l)
20614         [ $cnt != 184 ] && error "unexpected #files: $cnt"
20615
20616         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
20617         $LFS rmfid $DIR $FID1 || error "rmfid failed"
20618
20619         cnt=$(ls $DIR/$tdir | wc -l)
20620         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
20621 }
20622 run_test 421c "rm by fid against hardlinked files"
20623
20624 test_421d() {
20625         local cnt
20626         local FIDS
20627
20628         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20629                 skip "Need MDS version at least 2.12.54"
20630
20631         test_mkdir $DIR/$tdir
20632         createmany -o $DIR/$tdir/f 4097
20633         cnt=$(ls -1 $DIR/$tdir | wc -l)
20634         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
20635
20636         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
20637         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20638
20639         cnt=$(ls $DIR/$tdir | wc -l)
20640         rm -rf $DIR/$tdir
20641         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20642 }
20643 run_test 421d "rmfid en masse"
20644
20645 test_421e() {
20646         local cnt
20647         local FID
20648
20649         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20650         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20651                 skip "Need MDS version at least 2.12.54"
20652
20653         mkdir -p $DIR/$tdir
20654         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20655         createmany -o $DIR/$tdir/striped_dir/f 512
20656         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20657         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20658
20659         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20660                 sed "s/[/][^:]*://g")
20661         $LFS rmfid $DIR $FIDS || error "rmfid failed"
20662
20663         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20664         rm -rf $DIR/$tdir
20665         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20666 }
20667 run_test 421e "rmfid in DNE"
20668
20669 test_421f() {
20670         local cnt
20671         local FID
20672
20673         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20674                 skip "Need MDS version at least 2.12.54"
20675
20676         test_mkdir $DIR/$tdir
20677         touch $DIR/$tdir/f
20678         cnt=$(ls -1 $DIR/$tdir | wc -l)
20679         [ $cnt != 1 ] && error "unexpected #files: $cnt"
20680
20681         FID=$(lfs path2fid $DIR/$tdir/f)
20682         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
20683         # rmfid should fail
20684         cnt=$(ls -1 $DIR/$tdir | wc -l)
20685         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
20686
20687         chmod a+rw $DIR/$tdir
20688         ls -la $DIR/$tdir
20689         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
20690         # rmfid should fail
20691         cnt=$(ls -1 $DIR/$tdir | wc -l)
20692         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
20693
20694         rm -f $DIR/$tdir/f
20695         $RUNAS touch $DIR/$tdir/f
20696         FID=$(lfs path2fid $DIR/$tdir/f)
20697         echo "rmfid as root"
20698         $LFS rmfid $DIR $FID || error "rmfid as root failed"
20699         cnt=$(ls -1 $DIR/$tdir | wc -l)
20700         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
20701
20702         rm -f $DIR/$tdir/f
20703         $RUNAS touch $DIR/$tdir/f
20704         cnt=$(ls -1 $DIR/$tdir | wc -l)
20705         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
20706         FID=$(lfs path2fid $DIR/$tdir/f)
20707         # rmfid w/o user_fid2path mount option should fail
20708         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
20709         cnt=$(ls -1 $DIR/$tdir | wc -l)
20710         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
20711
20712         umount_client $MOUNT || "failed to umount client"
20713         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
20714                 "failed to mount client'"
20715
20716         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
20717         # rmfid should succeed
20718         cnt=$(ls -1 $DIR/$tdir | wc -l)
20719         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
20720
20721         # rmfid shouldn't allow to remove files due to dir's permission
20722         chmod a+rwx $DIR/$tdir
20723         touch $DIR/$tdir/f
20724         ls -la $DIR/$tdir
20725         FID=$(lfs path2fid $DIR/$tdir/f)
20726         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
20727
20728         umount_client $MOUNT || "failed to umount client"
20729         mount_client $MOUNT "$MOUNT_OPTS" ||
20730                 "failed to mount client'"
20731
20732 }
20733 run_test 421f "rmfid checks permissions"
20734
20735 test_421g() {
20736         local cnt
20737         local FIDS
20738
20739         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20740         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20741                 skip "Need MDS version at least 2.12.54"
20742
20743         mkdir -p $DIR/$tdir
20744         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
20745         createmany -o $DIR/$tdir/striped_dir/f 512
20746         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20747         [ $cnt != 512 ] && error "unexpected #files: $cnt"
20748
20749         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
20750                 sed "s/[/][^:]*://g")
20751
20752         rm -f $DIR/$tdir/striped_dir/f1*
20753         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
20754         removed=$((512 - cnt))
20755
20756         # few files have been just removed, so we expect
20757         # rmfid to fail on their fids
20758         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
20759         [ $removed != $errors ] && error "$errors != $removed"
20760
20761         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
20762         rm -rf $DIR/$tdir
20763         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
20764 }
20765 run_test 421g "rmfid to return errors properly"
20766
20767 prep_801() {
20768         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20769         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20770                 skip "Need server version at least 2.9.55"
20771
20772         start_full_debug_logging
20773 }
20774
20775 post_801() {
20776         stop_full_debug_logging
20777 }
20778
20779 barrier_stat() {
20780         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20781                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20782                            awk '/The barrier for/ { print $7 }')
20783                 echo $st
20784         else
20785                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
20786                 echo \'$st\'
20787         fi
20788 }
20789
20790 barrier_expired() {
20791         local expired
20792
20793         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
20794                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
20795                           awk '/will be expired/ { print $7 }')
20796         else
20797                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
20798         fi
20799
20800         echo $expired
20801 }
20802
20803 test_801a() {
20804         prep_801
20805
20806         echo "Start barrier_freeze at: $(date)"
20807         #define OBD_FAIL_BARRIER_DELAY          0x2202
20808         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20809         do_facet mgs $LCTL barrier_freeze $FSNAME 10 &
20810
20811         sleep 2
20812         local b_status=$(barrier_stat)
20813         echo "Got barrier status at: $(date)"
20814         [ "$b_status" = "'freezing_p1'" ] ||
20815                 error "(1) unexpected barrier status $b_status"
20816
20817         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20818         wait
20819         b_status=$(barrier_stat)
20820         [ "$b_status" = "'frozen'" ] ||
20821                 error "(2) unexpected barrier status $b_status"
20822
20823         local expired=$(barrier_expired)
20824         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
20825         sleep $((expired + 3))
20826
20827         b_status=$(barrier_stat)
20828         [ "$b_status" = "'expired'" ] ||
20829                 error "(3) unexpected barrier status $b_status"
20830
20831         do_facet mgs $LCTL barrier_freeze $FSNAME 10 ||
20832                 error "(4) fail to freeze barrier"
20833
20834         b_status=$(barrier_stat)
20835         [ "$b_status" = "'frozen'" ] ||
20836                 error "(5) unexpected barrier status $b_status"
20837
20838         echo "Start barrier_thaw at: $(date)"
20839         #define OBD_FAIL_BARRIER_DELAY          0x2202
20840         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
20841         do_facet mgs $LCTL barrier_thaw $FSNAME &
20842
20843         sleep 2
20844         b_status=$(barrier_stat)
20845         echo "Got barrier status at: $(date)"
20846         [ "$b_status" = "'thawing'" ] ||
20847                 error "(6) unexpected barrier status $b_status"
20848
20849         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
20850         wait
20851         b_status=$(barrier_stat)
20852         [ "$b_status" = "'thawed'" ] ||
20853                 error "(7) unexpected barrier status $b_status"
20854
20855         #define OBD_FAIL_BARRIER_FAILURE        0x2203
20856         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
20857         do_facet mgs $LCTL barrier_freeze $FSNAME
20858
20859         b_status=$(barrier_stat)
20860         [ "$b_status" = "'failed'" ] ||
20861                 error "(8) unexpected barrier status $b_status"
20862
20863         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
20864         do_facet mgs $LCTL barrier_thaw $FSNAME
20865
20866         post_801
20867 }
20868 run_test 801a "write barrier user interfaces and stat machine"
20869
20870 test_801b() {
20871         prep_801
20872
20873         mkdir $DIR/$tdir || error "(1) fail to mkdir"
20874         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
20875         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
20876         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
20877         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
20878
20879         cancel_lru_locks mdc
20880
20881         # 180 seconds should be long enough
20882         do_facet mgs $LCTL barrier_freeze $FSNAME 180
20883
20884         local b_status=$(barrier_stat)
20885         [ "$b_status" = "'frozen'" ] ||
20886                 error "(6) unexpected barrier status $b_status"
20887
20888         mkdir $DIR/$tdir/d0/d10 &
20889         mkdir_pid=$!
20890
20891         touch $DIR/$tdir/d1/f13 &
20892         touch_pid=$!
20893
20894         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
20895         ln_pid=$!
20896
20897         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
20898         mv_pid=$!
20899
20900         rm -f $DIR/$tdir/d4/f12 &
20901         rm_pid=$!
20902
20903         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
20904
20905         # To guarantee taht the 'stat' is not blocked
20906         b_status=$(barrier_stat)
20907         [ "$b_status" = "'frozen'" ] ||
20908                 error "(8) unexpected barrier status $b_status"
20909
20910         # let above commands to run at background
20911         sleep 5
20912
20913         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
20914         ps -p $touch_pid || error "(10) touch should be blocked"
20915         ps -p $ln_pid || error "(11) link should be blocked"
20916         ps -p $mv_pid || error "(12) rename should be blocked"
20917         ps -p $rm_pid || error "(13) unlink should be blocked"
20918
20919         b_status=$(barrier_stat)
20920         [ "$b_status" = "'frozen'" ] ||
20921                 error "(14) unexpected barrier status $b_status"
20922
20923         do_facet mgs $LCTL barrier_thaw $FSNAME
20924         b_status=$(barrier_stat)
20925         [ "$b_status" = "'thawed'" ] ||
20926                 error "(15) unexpected barrier status $b_status"
20927
20928         wait $mkdir_pid || error "(16) mkdir should succeed"
20929         wait $touch_pid || error "(17) touch should succeed"
20930         wait $ln_pid || error "(18) link should succeed"
20931         wait $mv_pid || error "(19) rename should succeed"
20932         wait $rm_pid || error "(20) unlink should succeed"
20933
20934         post_801
20935 }
20936 run_test 801b "modification will be blocked by write barrier"
20937
20938 test_801c() {
20939         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
20940
20941         prep_801
20942
20943         stop mds2 || error "(1) Fail to stop mds2"
20944
20945         do_facet mgs $LCTL barrier_freeze $FSNAME 30
20946
20947         local b_status=$(barrier_stat)
20948         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
20949                 do_facet mgs $LCTL barrier_thaw $FSNAME
20950                 error "(2) unexpected barrier status $b_status"
20951         }
20952
20953         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20954                 error "(3) Fail to rescan barrier bitmap"
20955
20956         do_facet mgs $LCTL barrier_freeze $FSNAME 10
20957
20958         b_status=$(barrier_stat)
20959         [ "$b_status" = "'frozen'" ] ||
20960                 error "(4) unexpected barrier status $b_status"
20961
20962         do_facet mgs $LCTL barrier_thaw $FSNAME
20963         b_status=$(barrier_stat)
20964         [ "$b_status" = "'thawed'" ] ||
20965                 error "(5) unexpected barrier status $b_status"
20966
20967         local devname=$(mdsdevname 2)
20968
20969         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
20970
20971         do_facet mgs $LCTL barrier_rescan $FSNAME ||
20972                 error "(7) Fail to rescan barrier bitmap"
20973
20974         post_801
20975 }
20976 run_test 801c "rescan barrier bitmap"
20977
20978 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
20979 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
20980 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
20981 saved_MOUNT_OPTS=$MOUNT_OPTS
20982
20983 cleanup_802a() {
20984         trap 0
20985
20986         stopall
20987         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
20988         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
20989         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
20990         MOUNT_OPTS=$saved_MOUNT_OPTS
20991         setupall
20992 }
20993
20994 test_802a() {
20995
20996         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
20997         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
20998                 skip "Need server version at least 2.9.55"
20999
21000         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21001
21002         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21003
21004         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21005                 error "(2) Fail to copy"
21006
21007         trap cleanup_802a EXIT
21008
21009         # sync by force before remount as readonly
21010         sync; sync_all_data; sleep 3; sync_all_data
21011
21012         stopall
21013
21014         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21015         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21016         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21017
21018         echo "Mount the server as read only"
21019         setupall server_only || error "(3) Fail to start servers"
21020
21021         echo "Mount client without ro should fail"
21022         mount_client $MOUNT &&
21023                 error "(4) Mount client without 'ro' should fail"
21024
21025         echo "Mount client with ro should succeed"
21026         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21027         mount_client $MOUNT ||
21028                 error "(5) Mount client with 'ro' should succeed"
21029
21030         echo "Modify should be refused"
21031         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21032
21033         echo "Read should be allowed"
21034         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21035                 error "(7) Read should succeed under ro mode"
21036
21037         cleanup_802a
21038 }
21039 run_test 802a "simulate readonly device"
21040
21041 test_802b() {
21042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21043         remote_mds_nodsh && skip "remote MDS with nodsh"
21044
21045         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21046                 skip "readonly option not available"
21047
21048         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21049
21050         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21051                 error "(2) Fail to copy"
21052
21053         # write back all cached data before setting MDT to readonly
21054         cancel_lru_locks
21055         sync_all_data
21056
21057         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21058         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21059
21060         echo "Modify should be refused"
21061         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21062
21063         echo "Read should be allowed"
21064         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21065                 error "(7) Read should succeed under ro mode"
21066
21067         # disable readonly
21068         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21069 }
21070 run_test 802b "be able to set MDTs to readonly"
21071
21072 test_803() {
21073         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21074         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21075                 skip "MDS needs to be newer than 2.10.54"
21076
21077         mkdir -p $DIR/$tdir
21078         # Create some objects on all MDTs to trigger related logs objects
21079         for idx in $(seq $MDSCOUNT); do
21080                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21081                         $DIR/$tdir/dir${idx} ||
21082                         error "Fail to create $DIR/$tdir/dir${idx}"
21083         done
21084
21085         sync; sleep 3
21086         wait_delete_completed # ensure old test cleanups are finished
21087         echo "before create:"
21088         $LFS df -i $MOUNT
21089         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21090
21091         for i in {1..10}; do
21092                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21093                         error "Fail to create $DIR/$tdir/foo$i"
21094         done
21095
21096         sync; sleep 3
21097         echo "after create:"
21098         $LFS df -i $MOUNT
21099         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21100
21101         # allow for an llog to be cleaned up during the test
21102         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21103                 error "before ($before_used) + 10 > after ($after_used)"
21104
21105         for i in {1..10}; do
21106                 rm -rf $DIR/$tdir/foo$i ||
21107                         error "Fail to remove $DIR/$tdir/foo$i"
21108         done
21109
21110         sleep 3 # avoid MDT return cached statfs
21111         wait_delete_completed
21112         echo "after unlink:"
21113         $LFS df -i $MOUNT
21114         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21115
21116         # allow for an llog to be created during the test
21117         [ $after_used -le $((before_used + 1)) ] ||
21118                 error "after ($after_used) > before ($before_used) + 1"
21119 }
21120 run_test 803 "verify agent object for remote object"
21121
21122 test_804() {
21123         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21124         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21125                 skip "MDS needs to be newer than 2.10.54"
21126         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21127
21128         mkdir -p $DIR/$tdir
21129         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21130                 error "Fail to create $DIR/$tdir/dir0"
21131
21132         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21133         local dev=$(mdsdevname 2)
21134
21135         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21136                 grep ${fid} || error "NOT found agent entry for dir0"
21137
21138         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21139                 error "Fail to create $DIR/$tdir/dir1"
21140
21141         touch $DIR/$tdir/dir1/foo0 ||
21142                 error "Fail to create $DIR/$tdir/dir1/foo0"
21143         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21144         local rc=0
21145
21146         for idx in $(seq $MDSCOUNT); do
21147                 dev=$(mdsdevname $idx)
21148                 do_facet mds${idx} \
21149                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21150                         grep ${fid} && rc=$idx
21151         done
21152
21153         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21154                 error "Fail to rename foo0 to foo1"
21155         if [ $rc -eq 0 ]; then
21156                 for idx in $(seq $MDSCOUNT); do
21157                         dev=$(mdsdevname $idx)
21158                         do_facet mds${idx} \
21159                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21160                         grep ${fid} && rc=$idx
21161                 done
21162         fi
21163
21164         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21165                 error "Fail to rename foo1 to foo2"
21166         if [ $rc -eq 0 ]; then
21167                 for idx in $(seq $MDSCOUNT); do
21168                         dev=$(mdsdevname $idx)
21169                         do_facet mds${idx} \
21170                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21171                         grep ${fid} && rc=$idx
21172                 done
21173         fi
21174
21175         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21176
21177         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21178                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21179         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21180                 error "Fail to rename foo2 to foo0"
21181         unlink $DIR/$tdir/dir1/foo0 ||
21182                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21183         rm -rf $DIR/$tdir/dir0 ||
21184                 error "Fail to rm $DIR/$tdir/dir0"
21185
21186         for idx in $(seq $MDSCOUNT); do
21187                 dev=$(mdsdevname $idx)
21188                 rc=0
21189
21190                 stop mds${idx}
21191                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21192                         rc=$?
21193                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21194                         error "mount mds$idx failed"
21195                 df $MOUNT > /dev/null 2>&1
21196
21197                 # e2fsck should not return error
21198                 [ $rc -eq 0 ] ||
21199                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21200         done
21201 }
21202 run_test 804 "verify agent entry for remote entry"
21203
21204 cleanup_805() {
21205         do_facet $SINGLEMDS zfs set quota=$old $fsset
21206         unlinkmany $DIR/$tdir/f- 1000000
21207         trap 0
21208 }
21209
21210 test_805() {
21211         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21212         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21213         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21214                 skip "netfree not implemented before 0.7"
21215         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21216                 skip "Need MDS version at least 2.10.57"
21217
21218         local fsset
21219         local freekb
21220         local usedkb
21221         local old
21222         local quota
21223         local pref="osd-zfs.lustre-MDT0000."
21224
21225         # limit available space on MDS dataset to meet nospace issue
21226         # quickly. then ZFS 0.7.2 can use reserved space if asked
21227         # properly (using netfree flag in osd_declare_destroy()
21228         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21229         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21230                 gawk '{print $3}')
21231         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21232         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21233         let "usedkb=usedkb-freekb"
21234         let "freekb=freekb/2"
21235         if let "freekb > 5000"; then
21236                 let "freekb=5000"
21237         fi
21238         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21239         trap cleanup_805 EXIT
21240         mkdir $DIR/$tdir
21241         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21242         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21243         rm -rf $DIR/$tdir || error "not able to remove"
21244         do_facet $SINGLEMDS zfs set quota=$old $fsset
21245         trap 0
21246 }
21247 run_test 805 "ZFS can remove from full fs"
21248
21249 # Size-on-MDS test
21250 check_lsom_data()
21251 {
21252         local file=$1
21253         local size=$($LFS getsom -s $file)
21254         local expect=$(stat -c %s $file)
21255
21256         [[ $size == $expect ]] ||
21257                 error "$file expected size: $expect, got: $size"
21258
21259         local blocks=$($LFS getsom -b $file)
21260         expect=$(stat -c %b $file)
21261         [[ $blocks == $expect ]] ||
21262                 error "$file expected blocks: $expect, got: $blocks"
21263 }
21264
21265 check_lsom_size()
21266 {
21267         local size=$($LFS getsom -s $1)
21268         local expect=$2
21269
21270         [[ $size == $expect ]] ||
21271                 error "$file expected size: $expect, got: $size"
21272 }
21273
21274 test_806() {
21275         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21276                 skip "Need MDS version at least 2.11.52"
21277
21278         local bs=1048576
21279
21280         touch $DIR/$tfile || error "touch $tfile failed"
21281
21282         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21283         save_lustre_params client "llite.*.xattr_cache" > $save
21284         lctl set_param llite.*.xattr_cache=0
21285         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21286
21287         # single-threaded write
21288         echo "Test SOM for single-threaded write"
21289         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21290                 error "write $tfile failed"
21291         check_lsom_size $DIR/$tfile $bs
21292
21293         local num=32
21294         local size=$(($num * $bs))
21295         local offset=0
21296         local i
21297
21298         echo "Test SOM for single client multi-threaded($num) write"
21299         $TRUNCATE $DIR/$tfile 0
21300         for ((i = 0; i < $num; i++)); do
21301                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21302                 local pids[$i]=$!
21303                 offset=$((offset + $bs))
21304         done
21305         for (( i=0; i < $num; i++ )); do
21306                 wait ${pids[$i]}
21307         done
21308         check_lsom_size $DIR/$tfile $size
21309
21310         $TRUNCATE $DIR/$tfile 0
21311         for ((i = 0; i < $num; i++)); do
21312                 offset=$((offset - $bs))
21313                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21314                 local pids[$i]=$!
21315         done
21316         for (( i=0; i < $num; i++ )); do
21317                 wait ${pids[$i]}
21318         done
21319         check_lsom_size $DIR/$tfile $size
21320
21321         # multi-client wirtes
21322         num=$(get_node_count ${CLIENTS//,/ })
21323         size=$(($num * $bs))
21324         offset=0
21325         i=0
21326
21327         echo "Test SOM for multi-client ($num) writes"
21328         $TRUNCATE $DIR/$tfile 0
21329         for client in ${CLIENTS//,/ }; do
21330                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21331                 local pids[$i]=$!
21332                 i=$((i + 1))
21333                 offset=$((offset + $bs))
21334         done
21335         for (( i=0; i < $num; i++ )); do
21336                 wait ${pids[$i]}
21337         done
21338         check_lsom_size $DIR/$tfile $offset
21339
21340         i=0
21341         $TRUNCATE $DIR/$tfile 0
21342         for client in ${CLIENTS//,/ }; do
21343                 offset=$((offset - $bs))
21344                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21345                 local pids[$i]=$!
21346                 i=$((i + 1))
21347         done
21348         for (( i=0; i < $num; i++ )); do
21349                 wait ${pids[$i]}
21350         done
21351         check_lsom_size $DIR/$tfile $size
21352
21353         # verify truncate
21354         echo "Test SOM for truncate"
21355         $TRUNCATE $DIR/$tfile 1048576
21356         check_lsom_size $DIR/$tfile 1048576
21357         $TRUNCATE $DIR/$tfile 1234
21358         check_lsom_size $DIR/$tfile 1234
21359
21360         # verify SOM blocks count
21361         echo "Verify SOM block count"
21362         $TRUNCATE $DIR/$tfile 0
21363         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21364                 error "failed to write file $tfile"
21365         check_lsom_data $DIR/$tfile
21366 }
21367 run_test 806 "Verify Lazy Size on MDS"
21368
21369 test_807() {
21370         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21371         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21372                 skip "Need MDS version at least 2.11.52"
21373
21374         # Registration step
21375         changelog_register || error "changelog_register failed"
21376         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21377         changelog_users $SINGLEMDS | grep -q $cl_user ||
21378                 error "User $cl_user not found in changelog_users"
21379
21380         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21381         save_lustre_params client "llite.*.xattr_cache" > $save
21382         lctl set_param llite.*.xattr_cache=0
21383         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21384
21385         rm -rf $DIR/$tdir || error "rm $tdir failed"
21386         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21387         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21388         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21389         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21390                 error "truncate $tdir/trunc failed"
21391
21392         local bs=1048576
21393         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21394                 error "write $tfile failed"
21395
21396         # multi-client wirtes
21397         local num=$(get_node_count ${CLIENTS//,/ })
21398         local offset=0
21399         local i=0
21400
21401         echo "Test SOM for multi-client ($num) writes"
21402         touch $DIR/$tfile || error "touch $tfile failed"
21403         $TRUNCATE $DIR/$tfile 0
21404         for client in ${CLIENTS//,/ }; do
21405                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21406                 local pids[$i]=$!
21407                 i=$((i + 1))
21408                 offset=$((offset + $bs))
21409         done
21410         for (( i=0; i < $num; i++ )); do
21411                 wait ${pids[$i]}
21412         done
21413
21414         sleep 5
21415         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21416         check_lsom_data $DIR/$tdir/trunc
21417         check_lsom_data $DIR/$tdir/single_dd
21418         check_lsom_data $DIR/$tfile
21419
21420         rm -rf $DIR/$tdir
21421         # Deregistration step
21422         changelog_deregister || error "changelog_deregister failed"
21423 }
21424 run_test 807 "verify LSOM syncing tool"
21425
21426 check_som_nologged()
21427 {
21428         local lines=$($LFS changelog $FSNAME-MDT0000 |
21429                 grep 'x=trusted.som' | wc -l)
21430         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21431 }
21432
21433 test_808() {
21434         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21435                 skip "Need MDS version at least 2.11.55"
21436
21437         # Registration step
21438         changelog_register || error "changelog_register failed"
21439
21440         touch $DIR/$tfile || error "touch $tfile failed"
21441         check_som_nologged
21442
21443         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21444                 error "write $tfile failed"
21445         check_som_nologged
21446
21447         $TRUNCATE $DIR/$tfile 1234
21448         check_som_nologged
21449
21450         $TRUNCATE $DIR/$tfile 1048576
21451         check_som_nologged
21452
21453         # Deregistration step
21454         changelog_deregister || error "changelog_deregister failed"
21455 }
21456 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21457
21458 check_som_nodata()
21459 {
21460         $LFS getsom $1
21461         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21462 }
21463
21464 test_809() {
21465         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21466                 skip "Need MDS version at least 2.11.56"
21467
21468         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21469                 error "failed to create DoM-only file $DIR/$tfile"
21470         touch $DIR/$tfile || error "touch $tfile failed"
21471         check_som_nodata $DIR/$tfile
21472
21473         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21474                 error "write $tfile failed"
21475         check_som_nodata $DIR/$tfile
21476
21477         $TRUNCATE $DIR/$tfile 1234
21478         check_som_nodata $DIR/$tfile
21479
21480         $TRUNCATE $DIR/$tfile 4097
21481         check_som_nodata $DIR/$file
21482 }
21483 run_test 809 "Verify no SOM xattr store for DoM-only files"
21484
21485 test_810() {
21486         local ORIG
21487         local CSUM
21488
21489         # t10 seem to dislike partial pages
21490         lctl set_param osc.*.checksum_type=adler
21491         lctl set_param fail_loc=0x411
21492         dd if=/dev/urandom of=$DIR/$tfile bs=10240 count=2
21493         ORIG=$(md5sum $DIR/$tfile)
21494         lctl set_param ldlm.namespaces.*osc*.lru_size=clear
21495         CSUM=$(md5sum $DIR/$tfile)
21496         set_checksum_type adler
21497         if [ "$ORIG" != "$CSUM" ]; then
21498                 error "$ORIG != $CSUM"
21499         fi
21500 }
21501 run_test 810 "partial page writes on ZFS (LU-11663)"
21502
21503 test_811() {
21504         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21505                 skip "Need MDS version at least 2.11.56"
21506
21507         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21508         do_facet mds1 $LCTL set_param fail_loc=0x165
21509         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21510
21511         stop mds1
21512         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21513
21514         sleep 5
21515         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21516                 error "MDD orphan cleanup thread not quit"
21517 }
21518 run_test 811 "orphan name stub can be cleaned up in startup"
21519
21520 test_812() {
21521         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21522                 skip "OST < 2.12.51 doesn't support this fail_loc"
21523         [ "$SHARED_KEY" = true ] &&
21524                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21525
21526         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21527         # ensure ost1 is connected
21528         stat $DIR/$tfile >/dev/null || error "can't stat"
21529         wait_osc_import_state client ost1 FULL
21530         # no locks, no reqs to let the connection idle
21531         cancel_lru_locks osc
21532
21533         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21534 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21535         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21536         wait_osc_import_state client ost1 CONNECTING
21537         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21538
21539         stat $DIR/$tfile >/dev/null || error "can't stat file"
21540 }
21541 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21542
21543 test_813() {
21544         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21545         [ -z "$file_heat_sav" ] && skip "no file heat support"
21546
21547         local readsample
21548         local writesample
21549         local readbyte
21550         local writebyte
21551         local readsample1
21552         local writesample1
21553         local readbyte1
21554         local writebyte1
21555
21556         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21557         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21558
21559         $LCTL set_param -n llite.*.file_heat=1
21560         echo "Turn on file heat"
21561         echo "Period second: $period_second, Decay percentage: $decay_pct"
21562
21563         echo "QQQQ" > $DIR/$tfile
21564         echo "QQQQ" > $DIR/$tfile
21565         echo "QQQQ" > $DIR/$tfile
21566         cat $DIR/$tfile > /dev/null
21567         cat $DIR/$tfile > /dev/null
21568         cat $DIR/$tfile > /dev/null
21569         cat $DIR/$tfile > /dev/null
21570
21571         local out=$($LFS heat_get $DIR/$tfile)
21572
21573         $LFS heat_get $DIR/$tfile
21574         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21575         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21576         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21577         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21578
21579         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21580         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21581         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21582         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21583
21584         sleep $((period_second + 3))
21585         echo "Sleep $((period_second + 3)) seconds..."
21586         # The recursion formula to calculate the heat of the file f is as
21587         # follow:
21588         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21589         # Where Hi is the heat value in the period between time points i*I and
21590         # (i+1)*I; Ci is the access count in the period; the symbol P refers
21591         # to the weight of Ci.
21592         out=$($LFS heat_get $DIR/$tfile)
21593         $LFS heat_get $DIR/$tfile
21594         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21595         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21596         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21597         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21598
21599         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
21600                 error "read sample ($readsample) is wrong"
21601         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
21602                 error "write sample ($writesample) is wrong"
21603         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
21604                 error "read bytes ($readbyte) is wrong"
21605         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
21606                 error "write bytes ($writebyte) is wrong"
21607
21608         echo "QQQQ" > $DIR/$tfile
21609         echo "QQQQ" > $DIR/$tfile
21610         echo "QQQQ" > $DIR/$tfile
21611         cat $DIR/$tfile > /dev/null
21612         cat $DIR/$tfile > /dev/null
21613         cat $DIR/$tfile > /dev/null
21614         cat $DIR/$tfile > /dev/null
21615
21616         sleep $((period_second + 3))
21617         echo "Sleep $((period_second + 3)) seconds..."
21618
21619         out=$($LFS heat_get $DIR/$tfile)
21620         $LFS heat_get $DIR/$tfile
21621         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21622         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21623         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21624         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21625
21626         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
21627                 4 * $decay_pct) / 100") -eq 1 ] ||
21628                 error "read sample ($readsample1) is wrong"
21629         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
21630                 3 * $decay_pct) / 100") -eq 1 ] ||
21631                 error "write sample ($writesample1) is wrong"
21632         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
21633                 20 * $decay_pct) / 100") -eq 1 ] ||
21634                 error "read bytes ($readbyte1) is wrong"
21635         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
21636                 15 * $decay_pct) / 100") -eq 1 ] ||
21637                 error "write bytes ($writebyte1) is wrong"
21638
21639         echo "Turn off file heat for the file $DIR/$tfile"
21640         $LFS heat_set -o $DIR/$tfile
21641
21642         echo "QQQQ" > $DIR/$tfile
21643         echo "QQQQ" > $DIR/$tfile
21644         echo "QQQQ" > $DIR/$tfile
21645         cat $DIR/$tfile > /dev/null
21646         cat $DIR/$tfile > /dev/null
21647         cat $DIR/$tfile > /dev/null
21648         cat $DIR/$tfile > /dev/null
21649
21650         out=$($LFS heat_get $DIR/$tfile)
21651         $LFS heat_get $DIR/$tfile
21652         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21653         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21654         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21655         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21656
21657         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21658         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21659         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21660         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21661
21662         echo "Trun on file heat for the file $DIR/$tfile"
21663         $LFS heat_set -O $DIR/$tfile
21664
21665         echo "QQQQ" > $DIR/$tfile
21666         echo "QQQQ" > $DIR/$tfile
21667         echo "QQQQ" > $DIR/$tfile
21668         cat $DIR/$tfile > /dev/null
21669         cat $DIR/$tfile > /dev/null
21670         cat $DIR/$tfile > /dev/null
21671         cat $DIR/$tfile > /dev/null
21672
21673         out=$($LFS heat_get $DIR/$tfile)
21674         $LFS heat_get $DIR/$tfile
21675         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21676         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21677         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21678         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21679
21680         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
21681         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
21682         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
21683         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
21684
21685         $LFS heat_set -c $DIR/$tfile
21686         $LCTL set_param -n llite.*.file_heat=0
21687         echo "Turn off file heat support for the Lustre filesystem"
21688
21689         echo "QQQQ" > $DIR/$tfile
21690         echo "QQQQ" > $DIR/$tfile
21691         echo "QQQQ" > $DIR/$tfile
21692         cat $DIR/$tfile > /dev/null
21693         cat $DIR/$tfile > /dev/null
21694         cat $DIR/$tfile > /dev/null
21695         cat $DIR/$tfile > /dev/null
21696
21697         out=$($LFS heat_get $DIR/$tfile)
21698         $LFS heat_get $DIR/$tfile
21699         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21700         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21701         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21702         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21703
21704         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
21705         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
21706         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
21707         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
21708
21709         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
21710         rm -f $DIR/$tfile
21711 }
21712 run_test 813 "File heat verfication"
21713
21714 test_814()
21715 {
21716         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
21717         echo -n y >> $DIR/$tfile
21718         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
21719         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
21720 }
21721 run_test 814 "sparse cp works as expected (LU-12361)"
21722
21723 test_815()
21724 {
21725         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
21726         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
21727 }
21728 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
21729
21730 test_816() {
21731         [ "$SHARED_KEY" = true ] &&
21732                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21733
21734         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21735         # ensure ost1 is connected
21736         stat $DIR/$tfile >/dev/null || error "can't stat"
21737         wait_osc_import_state client ost1 FULL
21738         # no locks, no reqs to let the connection idle
21739         cancel_lru_locks osc
21740         lru_resize_disable osc
21741         local before
21742         local now
21743         before=$($LCTL get_param -n \
21744                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21745
21746         wait_osc_import_state client ost1 IDLE
21747         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
21748         now=$($LCTL get_param -n \
21749               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
21750         [ $before == $now ] || error "lru_size changed $before != $now"
21751 }
21752 run_test 816 "do not reset lru_resize on idle reconnect"
21753
21754 cleanup_817() {
21755         umount $tmpdir
21756         exportfs -u localhost:$DIR/nfsexp
21757         rm -rf $DIR/nfsexp
21758 }
21759
21760 test_817() {
21761         systemctl restart nfs-server.service || skip "failed to restart nfsd"
21762
21763         mkdir -p $DIR/nfsexp
21764         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
21765                 error "failed to export nfs"
21766
21767         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
21768         stack_trap cleanup_817 EXIT
21769
21770         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
21771                 error "failed to mount nfs to $tmpdir"
21772
21773         cp /bin/true $tmpdir
21774         $DIR/nfsexp/true || error "failed to execute 'true' command"
21775 }
21776 run_test 817 "nfsd won't cache write lock for exec file"
21777
21778 #
21779 # tests that do cleanup/setup should be run at the end
21780 #
21781
21782 test_900() {
21783         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21784         local ls
21785
21786         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
21787         $LCTL set_param fail_loc=0x903
21788
21789         cancel_lru_locks MGC
21790
21791         FAIL_ON_ERROR=true cleanup
21792         FAIL_ON_ERROR=true setup
21793 }
21794 run_test 900 "umount should not race with any mgc requeue thread"
21795
21796 complete $SECONDS
21797 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
21798 check_and_cleanup_lustre
21799 if [ "$I_MOUNTED" != "yes" ]; then
21800         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
21801 fi
21802 exit_status