Whamcloud - gitweb
LU-12751 tests: add missing error()
[fs/lustre-release.git] / lustre / tests / sanity.sh
1 #!/bin/bash
2 #
3 # Run select tests by setting ONLY, or as arguments to the script.
4 # Skip specific tests by setting EXCEPT.
5 #
6 # e.g. ONLY="22 23" or ONLY="`seq 32 39`" or EXCEPT="31"
7 set -e
8
9 ONLY=${ONLY:-"$*"}
10
11 # Check Grants after these tests
12 GRANT_CHECK_LIST="$GRANT_CHECK_LIST 42a 42b 42c 42d 42e 63a 63b 64a 64b 64c 64d"
13
14 OSC=${OSC:-"osc"}
15
16 CC=${CC:-cc}
17 CREATETEST=${CREATETEST:-createtest}
18 LVERIFY=${LVERIFY:-ll_dirstripe_verify}
19 OPENFILE=${OPENFILE:-openfile}
20 OPENUNLINK=${OPENUNLINK:-openunlink}
21 READS=${READS:-"reads"}
22 MUNLINK=${MUNLINK:-munlink}
23 SOCKETSERVER=${SOCKETSERVER:-socketserver}
24 SOCKETCLIENT=${SOCKETCLIENT:-socketclient}
25 MEMHOG=${MEMHOG:-memhog}
26 DIRECTIO=${DIRECTIO:-directio}
27 ACCEPTOR_PORT=${ACCEPTOR_PORT:-988}
28 DEF_STRIPE_COUNT=-1
29 CHECK_GRANT=${CHECK_GRANT:-"yes"}
30 GRANT_CHECK_LIST=${GRANT_CHECK_LIST:-""}
31 export PARALLEL=${PARALLEL:-"no"}
32
33 TRACE=${TRACE:-""}
34 LUSTRE_TESTS_API_DIR=${LUSTRE_TESTS_API_DIR:-${LUSTRE}/tests/clientapi}
35 LUSTRE=${LUSTRE:-$(dirname $0)/..}
36 . $LUSTRE/tests/test-framework.sh
37 init_test_env $@
38
39 init_logging
40
41 ALWAYS_EXCEPT="$SANITY_EXCEPT "
42 # bug number for skipped test: LU-9693 LU-6493 LU-9693
43 ALWAYS_EXCEPT+="               42a     42b     42c "
44 # bug number:    LU-8411 LU-9054
45 ALWAYS_EXCEPT+=" 407     312 "
46
47 if $SHARED_KEY; then
48         # bug number:    LU-9795 LU-9795 LU-9795 LU-9795
49         ALWAYS_EXCEPT+=" 17n     60a     133g    300f "
50 fi
51
52 # skip the grant tests for ARM until they are fixed
53 if [[ $(uname -m) = aarch64 ]]; then
54         # bug number:    LU-11596
55         ALWAYS_EXCEPT+=" $GRANT_CHECK_LIST"
56         # bug number:    LU-11671 LU-11667 LU-4398
57         ALWAYS_EXCEPT+=" 45       317      817"
58 fi
59
60 #                                  5          12          (min)"
61 [ "$SLOW" = "no" ] && EXCEPT_SLOW="27m 64b 68 71 115 300o"
62
63 if [ "$mds1_FSTYPE" = "zfs" ]; then
64         # bug number for skipped test:
65         ALWAYS_EXCEPT="$ALWAYS_EXCEPT  "
66         #                                               13    (min)"
67         [ "$SLOW" = "no" ] && EXCEPT_SLOW="$EXCEPT_SLOW 51b"
68 fi
69
70 # Get the SLES distro version
71 #
72 # Returns a version string that should only be used in comparing
73 # strings returned by version_code()
74 sles_version_code()
75 {
76         local version=$(grep VERSION_ID /etc/os-release | cut -d'"' -f2)
77
78         # All SuSE Linux versions have one decimal. version_code expects two
79         local sles_version=$version.0
80         version_code $sles_version
81 }
82
83 # Check if we are running on Ubuntu or SLES so we can make decisions on
84 # what tests to run
85 if [ -r /etc/SuSE-release ]; then
86         sles_version=$(sles_version_code)
87         [ $sles_version -lt $(version_code 11.4.0) ] &&
88                 # bug number for skipped test: LU-4341
89                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  170"
90         [ $sles_version -lt $(version_code 12.0.0) ] &&
91                 # bug number for skipped test: LU-3703
92                 ALWAYS_EXCEPT="$ALWAYS_EXCEPT  234"
93 elif [ -r /etc/os-release ]; then
94         if grep -qi ubuntu /etc/os-release; then
95                 ubuntu_version=$(version_code $(sed -n -e 's/"//g' \
96                                                 -e 's/^VERSION=//p' \
97                                                 /etc/os-release |
98                                                 awk '{ print $1 }'))
99
100                 if [[ $ubuntu_version -gt $(version_code 16.0.0) ]]; then
101                         # bug number for skipped test:
102                         #                LU-10334 LU-10366
103                         ALWAYS_EXCEPT+=" 103a     410"
104                 fi
105         fi
106 fi
107
108 build_test_filter
109 FAIL_ON_ERROR=false
110
111 cleanup() {
112         echo -n "cln.."
113         pgrep ll_sa > /dev/null && { echo "There are ll_sa thread not exit!"; exit 20; }
114         cleanupall ${FORCE} $* || { echo "FAILed to clean up"; exit 20; }
115 }
116 setup() {
117         echo -n "mnt.."
118         load_modules
119         setupall || exit 10
120         echo "done"
121 }
122
123 check_swap_layouts_support()
124 {
125         $LCTL get_param -n llite.*.sbi_flags | grep -q layout ||
126                 skip "Does not support layout lock."
127 }
128
129 check_and_setup_lustre
130 DIR=${DIR:-$MOUNT}
131 assert_DIR
132
133 MAXFREE=${MAXFREE:-$((200000 * $OSTCOUNT))}
134
135 [ -f $DIR/d52a/foo ] && chattr -a $DIR/d52a/foo
136 [ -f $DIR/d52b/foo ] && chattr -i $DIR/d52b/foo
137 rm -rf $DIR/[Rdfs][0-9]*
138
139 # $RUNAS_ID may get set incorrectly somewhere else
140 [ $UID -eq 0 -a $RUNAS_ID -eq 0 ] &&
141         error "\$RUNAS_ID set to 0, but \$UID is also 0!"
142
143 check_runas_id $RUNAS_ID $RUNAS_GID $RUNAS
144
145 if [ "${ONLY}" = "MOUNT" ] ; then
146         echo "Lustre is up, please go on"
147         exit
148 fi
149
150 echo "preparing for tests involving mounts"
151 EXT2_DEV=${EXT2_DEV:-$TMP/SANITY.LOOP}
152 touch $EXT2_DEV
153 mke2fs -j -F $EXT2_DEV 8000 > /dev/null
154 echo # add a newline after mke2fs.
155
156 umask 077
157
158 OLDDEBUG=$(lctl get_param -n debug 2> /dev/null)
159 lctl set_param debug=-1 2> /dev/null || true
160 test_0a() {
161         touch $DIR/$tfile
162         $CHECKSTAT -t file $DIR/$tfile || error "$tfile is not a file"
163         rm $DIR/$tfile
164         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
165 }
166 run_test 0a "touch; rm ====================="
167
168 test_0b() {
169         chmod 0755 $DIR || error "chmod 0755 $DIR failed"
170         $CHECKSTAT -p 0755 $DIR || error "$DIR permission is not 0755"
171 }
172 run_test 0b "chmod 0755 $DIR ============================="
173
174 test_0c() {
175         $LCTL get_param mdc.*.import | grep "state: FULL" ||
176                 error "import not FULL"
177         $LCTL get_param mdc.*.import | grep "target: $FSNAME-MDT" ||
178                 error "bad target"
179 }
180 run_test 0c "check import proc"
181
182 test_0d() { # LU-3397
183         [ $MGS_VERSION -lt $(version_code 2.10.57) ] &&
184                 skip "proc exports not supported before 2.10.57"
185
186         local mgs_exp="mgs.MGS.exports"
187         local client_uuid=$($LCTL get_param -n mgc.*.uuid)
188         local exp_client_nid
189         local exp_client_version
190         local exp_val
191         local imp_val
192         local temp_imp=$DIR/$tfile.import
193         local temp_exp=$DIR/$tfile.export
194
195         # save mgc import file to $temp_imp
196         $LCTL get_param mgc.*.import | tee $temp_imp
197         # Check if client uuid is found in MGS export
198         for exp_client_nid in $(do_facet mgs $LCTL get_param -N $mgs_exp.*); do
199                 [ $(do_facet mgs $LCTL get_param -n $exp_client_nid.uuid) == \
200                         $client_uuid ] &&
201                         break;
202         done
203         # save mgs export file to $temp_exp
204         do_facet mgs $LCTL get_param $exp_client_nid.export | tee $temp_exp
205
206         # Compare the value of field "connect_flags"
207         imp_val=$(grep "connect_flags" $temp_imp)
208         exp_val=$(grep "connect_flags" $temp_exp)
209         [ "$exp_val" == "$imp_val" ] ||
210                 error "export flags '$exp_val' != import flags '$imp_val'"
211
212         # Compare the value of client version
213         exp_client_version=$(awk '/target_version:/ { print $2 }' $temp_exp)
214         exp_val=$(version_code $exp_client_version)
215         imp_val=$CLIENT_VERSION
216         [ "$exp_val" == "$imp_val" ] ||
217                 error "export client version '$exp_val' != '$imp_val'"
218 }
219 run_test 0d "check export proc ============================="
220
221 test_1() {
222         test_mkdir $DIR/$tdir
223         test_mkdir $DIR/$tdir/d2
224         mkdir $DIR/$tdir/d2 && error "we expect EEXIST, but not returned"
225         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a dir"
226         rmdir $DIR/$tdir/d2
227         rmdir $DIR/$tdir
228         $CHECKSTAT -a $DIR/$tdir || error "$tdir was not removed"
229 }
230 run_test 1 "mkdir; remkdir; rmdir"
231
232 test_2() {
233         test_mkdir $DIR/$tdir
234         touch $DIR/$tdir/$tfile || error "touch $tdir/$tfile failed"
235         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
236         rm -r $DIR/$tdir
237         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$file is not removed"
238 }
239 run_test 2 "mkdir; touch; rmdir; check file"
240
241 test_3() {
242         test_mkdir $DIR/$tdir
243         $CHECKSTAT -t dir $DIR/$tdir || error "$tdir is not a directory"
244         touch $DIR/$tdir/$tfile
245         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "$tdir/$tfile not a file"
246         rm -r $DIR/$tdir
247         $CHECKSTAT -a $DIR/$tdir || error "$tdir is not removed"
248 }
249 run_test 3 "mkdir; touch; rmdir; check dir"
250
251 # LU-4471 - failed rmdir on remote directories still removes directory on MDT0
252 test_4() {
253         test_mkdir -i 1 $DIR/$tdir
254
255         touch $DIR/$tdir/$tfile ||
256                 error "Create file under remote directory failed"
257
258         rmdir $DIR/$tdir &&
259                 error "Expect error removing in-use dir $DIR/$tdir"
260
261         test -d $DIR/$tdir || error "Remote directory disappeared"
262
263         rm -rf $DIR/$tdir || error "remove remote dir error"
264 }
265 run_test 4 "mkdir; touch dir/file; rmdir; checkdir (expect error)"
266
267 test_5() {
268         test_mkdir $DIR/$tdir
269         test_mkdir $DIR/$tdir/d2
270         chmod 0707 $DIR/$tdir/d2 || error "chmod 0707 $tdir/d2 failed"
271         $CHECKSTAT -t dir -p 0707 $DIR/$tdir/d2 || error "$tdir/d2 not mode 707"
272         $CHECKSTAT -t dir $DIR/$tdir/d2 || error "$tdir/d2 is not a directory"
273 }
274 run_test 5 "mkdir .../d5 .../d5/d2; chmod .../d5/d2"
275
276 test_6a() {
277         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
278         chmod 0666 $DIR/$tfile || error "chmod 0666 $tfile failed"
279         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
280                 error "$tfile does not have perm 0666 or UID $UID"
281         $RUNAS chmod 0444 $DIR/$tfile && error "chmod $tfile worked on UID $UID"
282         $CHECKSTAT -t file -p 0666 -u \#$UID $DIR/$tfile ||
283                 error "$tfile should be 0666 and owned by UID $UID"
284 }
285 run_test 6a "touch f6a; chmod f6a; $RUNAS chmod f6a (should return error) =="
286
287 test_6c() {
288         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
289
290         touch $DIR/$tfile
291         chown $RUNAS_ID $DIR/$tfile || error "chown $RUNAS_ID $file failed"
292         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
293                 error "$tfile should be owned by UID $RUNAS_ID"
294         $RUNAS chown $UID $DIR/$tfile && error "chown $UID $file succeeded"
295         $CHECKSTAT -t file -u \#$RUNAS_ID $DIR/$tfile ||
296                 error "$tfile should be owned by UID $RUNAS_ID"
297 }
298 run_test 6c "touch f6c; chown f6c; $RUNAS chown f6c (should return error) =="
299
300 test_6e() {
301         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
302
303         touch $DIR/$tfile
304         chgrp $RUNAS_ID $DIR/$tfile || error "chgrp $RUNAS_ID $file failed"
305         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
306                 error "$tfile should be owned by GID $UID"
307         $RUNAS chgrp $UID $DIR/$tfile && error "chgrp $UID $file succeeded"
308         $CHECKSTAT -t file -u \#$UID -g \#$RUNAS_ID $DIR/$tfile ||
309                 error "$tfile should be owned by UID $UID and GID $RUNAS_ID"
310 }
311 run_test 6e "touch+chgrp $tfile; $RUNAS chgrp $tfile (should return error)"
312
313 test_6g() {
314         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
315
316         test_mkdir $DIR/$tdir
317         chmod 777 $DIR/$tdir || error "chmod 0777 $tdir failed"
318         $RUNAS mkdir $DIR/$tdir/d || error "mkdir $tdir/d failed"
319         chmod g+s $DIR/$tdir/d || error "chmod g+s $tdir/d failed"
320         test_mkdir $DIR/$tdir/d/subdir
321         $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir/d/subdir ||
322                 error "$tdir/d/subdir should be GID $RUNAS_GID"
323         if [[ $MDSCOUNT -gt 1 ]]; then
324                 # check remote dir sgid inherite
325                 $LFS mkdir -i 0 $DIR/$tdir.local ||
326                         error "mkdir $tdir.local failed"
327                 chmod g+s $DIR/$tdir.local ||
328                         error "chmod $tdir.local failed"
329                 chgrp $RUNAS_GID $DIR/$tdir.local ||
330                         error "chgrp $tdir.local failed"
331                 $LFS mkdir -i 1 $DIR/$tdir.local/$tdir.remote ||
332                         error "mkdir $tdir.remote failed"
333                 $CHECKSTAT -g \#$RUNAS_GID $DIR/$tdir.local/$tdir.remote ||
334                         error "$tdir.remote should be owned by $UID.$RUNAS_ID"
335                 $CHECKSTAT -p 02755 $DIR/$tdir.local/$tdir.remote ||
336                         error "$tdir.remote should be mode 02755"
337         fi
338 }
339 run_test 6g "verify new dir in sgid dir inherits group"
340
341 test_6h() { # bug 7331
342         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID"
343
344         touch $DIR/$tfile || error "touch failed"
345         chown $RUNAS_ID:$RUNAS_GID $DIR/$tfile || error "initial chown failed"
346         $RUNAS -G$RUNAS_GID chown $RUNAS_ID:0 $DIR/$tfile &&
347                 error "chown $RUNAS_ID:0 $tfile worked as GID $RUNAS_GID"
348         $CHECKSTAT -t file -u \#$RUNAS_ID -g \#$RUNAS_GID $DIR/$tfile ||
349                 error "$tdir/$tfile should be UID $RUNAS_UID GID $RUNAS_GID"
350 }
351 run_test 6h "$RUNAS chown RUNAS_ID.0 .../$tfile (should return error)"
352
353 test_7a() {
354         test_mkdir $DIR/$tdir
355         $MCREATE $DIR/$tdir/$tfile
356         chmod 0666 $DIR/$tdir/$tfile
357         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
358                 error "$tdir/$tfile should be mode 0666"
359 }
360 run_test 7a "mkdir .../d7; mcreate .../d7/f; chmod .../d7/f ===="
361
362 test_7b() {
363         if [ ! -d $DIR/$tdir ]; then
364                 test_mkdir $DIR/$tdir
365         fi
366         $MCREATE $DIR/$tdir/$tfile
367         echo -n foo > $DIR/$tdir/$tfile
368         [ "$(cat $DIR/$tdir/$tfile)" = "foo" ] || error "$tdir/$tfile not 'foo'"
369         $CHECKSTAT -t file -s 3 $DIR/$tdir/$tfile || error "$tfile size not 3"
370 }
371 run_test 7b "mkdir .../d7; mcreate d7/f2; echo foo > d7/f2 ====="
372
373 test_8() {
374         test_mkdir $DIR/$tdir
375         touch $DIR/$tdir/$tfile
376         chmod 0666 $DIR/$tdir/$tfile
377         $CHECKSTAT -t file -p 0666 $DIR/$tdir/$tfile ||
378                 error "$tfile mode not 0666"
379 }
380 run_test 8 "mkdir .../d8; touch .../d8/f; chmod .../d8/f ======="
381
382 test_9() {
383         test_mkdir $DIR/$tdir
384         test_mkdir $DIR/$tdir/d2
385         test_mkdir $DIR/$tdir/d2/d3
386         $CHECKSTAT -t dir $DIR/$tdir/d2/d3 || error "$tdir/d2/d3 not a dir"
387 }
388 run_test 9 "mkdir .../d9 .../d9/d2 .../d9/d2/d3 ================"
389
390 test_10() {
391         test_mkdir $DIR/$tdir
392         test_mkdir $DIR/$tdir/d2
393         touch $DIR/$tdir/d2/$tfile
394         $CHECKSTAT -t file $DIR/$tdir/d2/$tfile ||
395                 error "$tdir/d2/$tfile not a file"
396 }
397 run_test 10 "mkdir .../d10 .../d10/d2; touch .../d10/d2/f ======"
398
399 test_11() {
400         test_mkdir $DIR/$tdir
401         test_mkdir $DIR/$tdir/d2
402         chmod 0666 $DIR/$tdir/d2
403         chmod 0705 $DIR/$tdir/d2
404         $CHECKSTAT -t dir -p 0705 $DIR/$tdir/d2 ||
405                 error "$tdir/d2 mode not 0705"
406 }
407 run_test 11 "mkdir .../d11 d11/d2; chmod .../d11/d2 ============"
408
409 test_12() {
410         test_mkdir $DIR/$tdir
411         touch $DIR/$tdir/$tfile
412         chmod 0666 $DIR/$tdir/$tfile
413         chmod 0654 $DIR/$tdir/$tfile
414         $CHECKSTAT -t file -p 0654 $DIR/$tdir/$tfile ||
415                 error "$tdir/d2 mode not 0654"
416 }
417 run_test 12 "touch .../d12/f; chmod .../d12/f .../d12/f ========"
418
419 test_13() {
420         test_mkdir $DIR/$tdir
421         dd if=/dev/zero of=$DIR/$tdir/$tfile count=10
422         >  $DIR/$tdir/$tfile
423         $CHECKSTAT -t file -s 0 $DIR/$tdir/$tfile ||
424                 error "$tdir/$tfile size not 0 after truncate"
425 }
426 run_test 13 "creat .../d13/f; dd .../d13/f; > .../d13/f ========"
427
428 test_14() {
429         test_mkdir $DIR/$tdir
430         touch $DIR/$tdir/$tfile
431         rm $DIR/$tdir/$tfile
432         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
433 }
434 run_test 14 "touch .../d14/f; rm .../d14/f; rm .../d14/f ======="
435
436 test_15() {
437         test_mkdir $DIR/$tdir
438         touch $DIR/$tdir/$tfile
439         mv $DIR/$tdir/$tfile $DIR/$tdir/${tfile}_2
440         $CHECKSTAT -t file $DIR/$tdir/${tfile}_2 ||
441                 error "$tdir/${tfile_2} not a file after rename"
442         rm $DIR/$tdir/${tfile}_2 || error "unlink failed after rename"
443 }
444 run_test 15 "touch .../d15/f; mv .../d15/f .../d15/f2 =========="
445
446 test_16() {
447         test_mkdir $DIR/$tdir
448         touch $DIR/$tdir/$tfile
449         rm -rf $DIR/$tdir/$tfile
450         $CHECKSTAT -a $DIR/$tdir/$tfile || error "$tdir/$tfile not removed"
451 }
452 run_test 16 "touch .../d16/f; rm -rf .../d16/f"
453
454 test_17a() {
455         test_mkdir $DIR/$tdir
456         touch $DIR/$tdir/$tfile
457         ln -s $DIR/$tdir/$tfile $DIR/$tdir/l-exist
458         ls -l $DIR/$tdir
459         $CHECKSTAT -l $DIR/$tdir/$tfile $DIR/$tdir/l-exist ||
460                 error "$tdir/l-exist not a symlink"
461         $CHECKSTAT -f -t f $DIR/$tdir/l-exist ||
462                 error "$tdir/l-exist not referencing a file"
463         rm -f $DIR/$tdir/l-exist
464         $CHECKSTAT -a $DIR/$tdir/l-exist || error "$tdir/l-exist not removed"
465 }
466 run_test 17a "symlinks: create, remove (real)"
467
468 test_17b() {
469         test_mkdir $DIR/$tdir
470         ln -s no-such-file $DIR/$tdir/l-dangle
471         ls -l $DIR/$tdir
472         $CHECKSTAT -l no-such-file $DIR/$tdir/l-dangle ||
473                 error "$tdir/l-dangle not referencing no-such-file"
474         $CHECKSTAT -fa $DIR/$tdir/l-dangle ||
475                 error "$tdir/l-dangle not referencing non-existent file"
476         rm -f $DIR/$tdir/l-dangle
477         $CHECKSTAT -a $DIR/$tdir/l-dangle || error "$tdir/l-dangle not removed"
478 }
479 run_test 17b "symlinks: create, remove (dangling)"
480
481 test_17c() { # bug 3440 - don't save failed open RPC for replay
482         test_mkdir $DIR/$tdir
483         ln -s foo $DIR/$tdir/$tfile
484         cat $DIR/$tdir/$tfile && error "opened non-existent symlink" || true
485 }
486 run_test 17c "symlinks: open dangling (should return error)"
487
488 test_17d() {
489         test_mkdir $DIR/$tdir
490         ln -s foo $DIR/$tdir/$tfile
491         touch $DIR/$tdir/$tfile || error "creating to new symlink"
492 }
493 run_test 17d "symlinks: create dangling"
494
495 test_17e() {
496         test_mkdir $DIR/$tdir
497         local foo=$DIR/$tdir/$tfile
498         ln -s $foo $foo || error "create symlink failed"
499         ls -l $foo || error "ls -l failed"
500         ls $foo && error "ls not failed" || true
501 }
502 run_test 17e "symlinks: create recursive symlink (should return error)"
503
504 test_17f() {
505         test_mkdir $DIR/$tdir
506         ln -s 1234567890/2234567890/3234567890/4234567890 $DIR/$tdir/111
507         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890 $DIR/$tdir/222
508         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890 $DIR/$tdir/333
509         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890 $DIR/$tdir/444
510         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890 $DIR/$tdir/555
511         ln -s 1234567890/2234567890/3234567890/4234567890/5234567890/6234567890/7234567890/8234567890/9234567890/a234567890/b234567890/c234567890/d234567890/f234567890/aaaaaaaaaa/bbbbbbbbbb/cccccccccc/dddddddddd/eeeeeeeeee/ffffffffff/ $DIR/$tdir/666
512         ls -l  $DIR/$tdir
513 }
514 run_test 17f "symlinks: long and very long symlink name"
515
516 # str_repeat(S, N) generate a string that is string S repeated N times
517 str_repeat() {
518         local s=$1
519         local n=$2
520         local ret=''
521         while [ $((n -= 1)) -ge 0 ]; do
522                 ret=$ret$s
523         done
524         echo $ret
525 }
526
527 # Long symlinks and LU-2241
528 test_17g() {
529         test_mkdir $DIR/$tdir
530         local TESTS="59 60 61 4094 4095"
531
532         # Fix for inode size boundary in 2.1.4
533         [ $MDS1_VERSION -lt $(version_code 2.1.4) ] &&
534                 TESTS="4094 4095"
535
536         # Patch not applied to 2.2 or 2.3 branches
537         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
538         [ $MDS1_VERSION -le $(version_code 2.3.55) ] &&
539                 TESTS="4094 4095"
540
541         # skip long symlink name for rhel6.5.
542         # rhel6.5 has a limit (PATH_MAX - sizeof(struct filename))
543         grep -q '6.5' /etc/redhat-release &>/dev/null &&
544                 TESTS="59 60 61 4062 4063"
545
546         for i in $TESTS; do
547                 local SYMNAME=$(str_repeat 'x' $i)
548                 ln -s $SYMNAME $DIR/$tdir/f$i || error "failed $i-char symlink"
549                 readlink $DIR/$tdir/f$i || error "failed $i-char readlink"
550         done
551 }
552 run_test 17g "symlinks: really long symlink name and inode boundaries"
553
554 test_17h() { #bug 17378
555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
556         remote_mds_nodsh && skip "remote MDS with nodsh"
557
558         local mdt_idx
559
560         test_mkdir $DIR/$tdir
561         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
562         $LFS setstripe -c -1 $DIR/$tdir
563         #define OBD_FAIL_MDS_LOV_PREP_CREATE 0x141
564         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000141
565         touch $DIR/$tdir/$tfile || true
566 }
567 run_test 17h "create objects: lov_free_memmd() doesn't lbug"
568
569 test_17i() { #bug 20018
570         [ $PARALLEL == "yes" ] && skip "skip parallel run"
571         remote_mds_nodsh && skip "remote MDS with nodsh"
572
573         local foo=$DIR/$tdir/$tfile
574         local mdt_idx
575
576         test_mkdir -c1 $DIR/$tdir
577         mdt_idx=$($LFS getdirstripe -i $DIR/$tdir)
578         ln -s $foo $foo || error "create symlink failed"
579 #define OBD_FAIL_MDS_READLINK_EPROTO     0x143
580         do_facet mds$((mdt_idx + 1)) lctl set_param fail_loc=0x80000143
581         ls -l $foo && error "error not detected"
582         return 0
583 }
584 run_test 17i "don't panic on short symlink (should return error)"
585
586 test_17k() { #bug 22301
587         [ $PARALLEL == "yes" ] && skip "skip parallel run"
588         [[ -z "$(which rsync 2>/dev/null)" ]] &&
589                 skip "no rsync command"
590         rsync --help | grep -q xattr ||
591                 skip_env "$(rsync --version | head -n1) does not support xattrs"
592         test_mkdir $DIR/$tdir
593         test_mkdir $DIR/$tdir.new
594         touch $DIR/$tdir/$tfile
595         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
596         rsync -av -X $DIR/$tdir/ $DIR/$tdir.new ||
597                 error "rsync failed with xattrs enabled"
598 }
599 run_test 17k "symlinks: rsync with xattrs enabled"
600
601 test_17l() { # LU-279
602         [[ -z "$(which getfattr 2>/dev/null)" ]] &&
603                 skip "no getfattr command"
604
605         test_mkdir $DIR/$tdir
606         touch $DIR/$tdir/$tfile
607         ln -s $DIR/$tdir/$tfile $DIR/$tdir/$tfile.lnk
608         for path in "$DIR/$tdir" "$DIR/$tdir/$tfile" "$DIR/$tdir/$tfile.lnk"; do
609                 # -h to not follow symlinks. -m '' to list all the xattrs.
610                 # grep to remove first line: '# file: $path'.
611                 for xattr in `getfattr -hm '' $path 2>/dev/null | grep -v '^#'`;
612                 do
613                         lgetxattr_size_check $path $xattr ||
614                                 error "lgetxattr_size_check $path $xattr failed"
615                 done
616         done
617 }
618 run_test 17l "Ensure lgetxattr's returned xattr size is consistent"
619
620 # LU-1540
621 test_17m() {
622         [ $PARALLEL == "yes" ] && skip "skip parallel run"
623         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
624         remote_mds_nodsh && skip "remote MDS with nodsh"
625         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
626         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
627                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
628
629         local short_sym="0123456789"
630         local wdir=$DIR/$tdir
631         local i
632
633         test_mkdir $wdir
634         long_sym=$short_sym
635         # create a long symlink file
636         for ((i = 0; i < 4; ++i)); do
637                 long_sym=${long_sym}${long_sym}
638         done
639
640         echo "create 512 short and long symlink files under $wdir"
641         for ((i = 0; i < 256; ++i)); do
642                 ln -sf ${long_sym}"a5a5" $wdir/long-$i
643                 ln -sf ${short_sym}"a5a5" $wdir/short-$i
644         done
645
646         echo "erase them"
647         rm -f $wdir/*
648         sync
649         wait_delete_completed
650
651         echo "recreate the 512 symlink files with a shorter string"
652         for ((i = 0; i < 512; ++i)); do
653                 # rewrite the symlink file with a shorter string
654                 ln -sf ${long_sym} $wdir/long-$i || error "long_sym failed"
655                 ln -sf ${short_sym} $wdir/short-$i || error "short_sym failed"
656         done
657
658         local mds_index=$(($($LFS getstripe -m $wdir) + 1))
659         local devname=$(mdsdevname $mds_index)
660
661         echo "stop and checking mds${mds_index}:"
662         # e2fsck should not return error
663         stop mds${mds_index}
664         run_e2fsck $(facet_active_host mds${mds_index}) $devname -n
665         rc=$?
666
667         start mds${mds_index} $devname $MDS_MOUNT_OPTS ||
668                 error "start mds${mds_index} failed"
669         df $MOUNT > /dev/null 2>&1
670         [ $rc -eq 0 ] ||
671                 error "e2fsck detected error for short/long symlink: rc=$rc"
672         rm -f $wdir/*
673 }
674 run_test 17m "run e2fsck against MDT which contains short/long symlink"
675
676 check_fs_consistency_17n() {
677         local mdt_index
678         local rc=0
679
680         # create/unlink in 17n only change 2 MDTs(MDT1/MDT2),
681         # so it only check MDT1/MDT2 instead of all of MDTs.
682         for mdt_index in 1 2; do
683                 local devname=$(mdsdevname $mdt_index)
684                 # e2fsck should not return error
685                 stop mds${mdt_index}
686                 run_e2fsck $(facet_active_host mds$mdt_index) $devname -n ||
687                         rc=$((rc + $?))
688
689                 start mds${mdt_index} $devname $MDS_MOUNT_OPTS ||
690                         error "mount mds$mdt_index failed"
691                 df $MOUNT > /dev/null 2>&1
692         done
693         return $rc
694 }
695
696 test_17n() {
697         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
698         [ $PARALLEL == "yes" ] && skip "skip parallel run"
699         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
700         remote_mds_nodsh && skip "remote MDS with nodsh"
701         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] &&
702         [ $MDS1_VERSION -le $(version_code 2.2.93) ] &&
703                 skip "MDS 2.2.0-2.2.93 do not NUL-terminate symlinks"
704
705         local i
706
707         test_mkdir $DIR/$tdir
708         for ((i=0; i<10; i++)); do
709                 $LFS mkdir -i1 -c2 $DIR/$tdir/remote_dir_${i} ||
710                         error "create remote dir error $i"
711                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
712                         error "create files under remote dir failed $i"
713         done
714
715         check_fs_consistency_17n ||
716                 error "e2fsck report error after create files under remote dir"
717
718         for ((i = 0; i < 10; i++)); do
719                 rm -rf $DIR/$tdir/remote_dir_${i} ||
720                         error "destroy remote dir error $i"
721         done
722
723         check_fs_consistency_17n ||
724                 error "e2fsck report error after unlink files under remote dir"
725
726         [ $MDS1_VERSION -lt $(version_code 2.4.50) ] &&
727                 skip "lustre < 2.4.50 does not support migrate mv"
728
729         for ((i = 0; i < 10; i++)); do
730                 mkdir -p $DIR/$tdir/remote_dir_${i}
731                 createmany -o $DIR/$tdir/remote_dir_${i}/f 10 ||
732                         error "create files under remote dir failed $i"
733                 $LFS migrate --mdt-index 1 $DIR/$tdir/remote_dir_${i} ||
734                         error "migrate remote dir error $i"
735         done
736         check_fs_consistency_17n || error "e2fsck report error after migration"
737
738         for ((i = 0; i < 10; i++)); do
739                 rm -rf $DIR/$tdir/remote_dir_${i} ||
740                         error "destroy remote dir error $i"
741         done
742
743         check_fs_consistency_17n || error "e2fsck report error after unlink"
744 }
745 run_test 17n "run e2fsck against master/slave MDT which contains remote dir"
746
747 test_17o() {
748         remote_mds_nodsh && skip "remote MDS with nodsh"
749         [ $MDS1_VERSION -lt $(version_code 2.3.64) ] &&
750                 skip "Need MDS version at least 2.3.64"
751
752         local wdir=$DIR/${tdir}o
753         local mdt_index
754         local rc=0
755
756         test_mkdir $wdir
757         touch $wdir/$tfile
758         mdt_index=$($LFS getstripe -m $wdir/$tfile)
759         mdt_index=$((mdt_index + 1))
760
761         cancel_lru_locks mdc
762         #fail mds will wait the failover finish then set
763         #following fail_loc to avoid interfer the recovery process.
764         fail mds${mdt_index}
765
766         #define OBD_FAIL_OSD_LMA_INCOMPAT 0x194
767         do_facet mds${mdt_index} lctl set_param fail_loc=0x194
768         ls -l $wdir/$tfile && rc=1
769         do_facet mds${mdt_index} lctl set_param fail_loc=0
770         [[ $rc -eq 0 ]] || error "stat file should fail"
771 }
772 run_test 17o "stat file with incompat LMA feature"
773
774 test_18() {
775         touch $DIR/$tfile || error "Failed to touch $DIR/$tfile: $?"
776         ls $DIR || error "Failed to ls $DIR: $?"
777 }
778 run_test 18 "touch .../f ; ls ... =============================="
779
780 test_19a() {
781         touch $DIR/$tfile
782         ls -l $DIR
783         rm $DIR/$tfile
784         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
785 }
786 run_test 19a "touch .../f19 ; ls -l ... ; rm .../f19 ==========="
787
788 test_19b() {
789         ls -l $DIR/$tfile && error "ls -l $tfile failed"|| true
790 }
791 run_test 19b "ls -l .../f19 (should return error) =============="
792
793 test_19c() {
794         [ $RUNAS_ID -eq $UID ] &&
795                 skip_env "RUNAS_ID = UID = $UID -- skipping"
796
797         $RUNAS touch $DIR/$tfile && error "create non-root file failed" || true
798 }
799 run_test 19c "$RUNAS touch .../f19 (should return error) =="
800
801 test_19d() {
802         cat $DIR/f19 && error || true
803 }
804 run_test 19d "cat .../f19 (should return error) =============="
805
806 test_20() {
807         touch $DIR/$tfile
808         rm $DIR/$tfile
809         touch $DIR/$tfile
810         rm $DIR/$tfile
811         touch $DIR/$tfile
812         rm $DIR/$tfile
813         $CHECKSTAT -a $DIR/$tfile || error "$tfile was not removed"
814 }
815 run_test 20 "touch .../f ; ls -l ..."
816
817 test_21() {
818         test_mkdir $DIR/$tdir
819         [ -f $DIR/$tdir/dangle ] && rm -f $DIR/$tdir/dangle
820         ln -s dangle $DIR/$tdir/link
821         echo foo >> $DIR/$tdir/link
822         cat $DIR/$tdir/dangle
823         $CHECKSTAT -t link $DIR/$tdir/link || error "$tdir/link not a link"
824         $CHECKSTAT -f -t file $DIR/$tdir/link ||
825                 error "$tdir/link not linked to a file"
826 }
827 run_test 21 "write to dangling link"
828
829 test_22() {
830         local wdir=$DIR/$tdir
831         test_mkdir $wdir
832         chown $RUNAS_ID:$RUNAS_GID $wdir
833         (cd $wdir || error "cd $wdir failed";
834                 $RUNAS tar cf - /etc/hosts /etc/sysconfig/network |
835                 $RUNAS tar xf -)
836         ls -lR $wdir/etc || error "ls -lR $wdir/etc failed"
837         $CHECKSTAT -t dir $wdir/etc || error "checkstat -t dir failed"
838         $CHECKSTAT -u \#$RUNAS_ID -g \#$RUNAS_GID $wdir/etc ||
839                 error "checkstat -u failed"
840 }
841 run_test 22 "unpack tar archive as non-root user"
842
843 # was test_23
844 test_23a() {
845         test_mkdir $DIR/$tdir
846         local file=$DIR/$tdir/$tfile
847
848         openfile -f O_CREAT:O_EXCL $file || error "$file create failed"
849         openfile -f O_CREAT:O_EXCL $file &&
850                 error "$file recreate succeeded" || true
851 }
852 run_test 23a "O_CREAT|O_EXCL in subdir"
853
854 test_23b() { # bug 18988
855         test_mkdir $DIR/$tdir
856         local file=$DIR/$tdir/$tfile
857
858         rm -f $file
859         echo foo > $file || error "write filed"
860         echo bar >> $file || error "append filed"
861         $CHECKSTAT -s 8 $file || error "wrong size"
862         rm $file
863 }
864 run_test 23b "O_APPEND check"
865
866 # LU-9409, size with O_APPEND and tiny writes
867 test_23c() {
868         local file=$DIR/$tfile
869
870         # single dd
871         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800
872         $CHECKSTAT -s 6400 $file || error "wrong size, expected 6400"
873         rm -f $file
874
875         # racing tiny writes
876         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
877         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=800 &
878         wait
879         $CHECKSTAT -s 12800 $file || error "wrong size, expected 12800"
880         rm -f $file
881
882         #racing tiny & normal writes
883         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4096 count=4 &
884         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=8 count=100 &
885         wait
886         $CHECKSTAT -s 17184 $file || error "wrong size, expected 17184"
887         rm -f $file
888
889         #racing tiny & normal writes 2, ugly numbers
890         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=4099 count=11 &
891         dd conv=notrunc oflag=append if=/dev/zero of=$file bs=17 count=173 &
892         wait
893         $CHECKSTAT -s 48030 $file || error "wrong size, expected 48030"
894         rm -f $file
895 }
896 run_test 23c "O_APPEND size checks for tiny writes"
897
898 # LU-11069 file offset is correct after appending writes
899 test_23d() {
900         local file=$DIR/$tfile
901         local offset
902
903         echo CentaurHauls > $file
904         offset=$($MULTIOP $file oO_WRONLY:O_APPEND:w13Zp)
905         if ((offset != 26)); then
906                 error "wrong offset, expected 26, got '$offset'"
907         fi
908 }
909 run_test 23d "file offset is correct after appending writes"
910
911 # rename sanity
912 test_24a() {
913         echo '-- same directory rename'
914         test_mkdir $DIR/$tdir
915         touch $DIR/$tdir/$tfile.1
916         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
917         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
918 }
919 run_test 24a "rename file to non-existent target"
920
921 test_24b() {
922         test_mkdir $DIR/$tdir
923         touch $DIR/$tdir/$tfile.{1,2}
924         mv $DIR/$tdir/$tfile.1 $DIR/$tdir/$tfile.2
925         $CHECKSTAT -a $DIR/$tdir/$tfile.1 || error "$tfile.1 exists"
926         $CHECKSTAT -t file $DIR/$tdir/$tfile.2 || error "$tfile.2 not a file"
927 }
928 run_test 24b "rename file to existing target"
929
930 test_24c() {
931         test_mkdir $DIR/$tdir
932         test_mkdir $DIR/$tdir/d$testnum.1
933         mv $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
934         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
935         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
936 }
937 run_test 24c "rename directory to non-existent target"
938
939 test_24d() {
940         test_mkdir -c1 $DIR/$tdir
941         test_mkdir -c1 $DIR/$tdir/d$testnum.1
942         test_mkdir -c1 $DIR/$tdir/d$testnum.2
943         mrename $DIR/$tdir/d$testnum.1 $DIR/$tdir/d$testnum.2
944         $CHECKSTAT -a $DIR/$tdir/d$testnum.1 || error "d$testnum.1 exists"
945         $CHECKSTAT -t dir $DIR/$tdir/d$testnum.2 || error "d$testnum.2 not dir"
946 }
947 run_test 24d "rename directory to existing target"
948
949 test_24e() {
950         echo '-- cross directory renames --'
951         test_mkdir $DIR/R5a
952         test_mkdir $DIR/R5b
953         touch $DIR/R5a/f
954         mv $DIR/R5a/f $DIR/R5b/g
955         $CHECKSTAT -a $DIR/R5a/f || error "$DIR/R5a/f exists"
956         $CHECKSTAT -t file $DIR/R5b/g || error "$DIR/R5b/g not file type"
957 }
958 run_test 24e "touch .../R5a/f; rename .../R5a/f .../R5b/g ======"
959
960 test_24f() {
961         test_mkdir $DIR/R6a
962         test_mkdir $DIR/R6b
963         touch $DIR/R6a/f $DIR/R6b/g
964         mv $DIR/R6a/f $DIR/R6b/g
965         $CHECKSTAT -a $DIR/R6a/f || error "$DIR/R6a/f exists"
966         $CHECKSTAT -t file $DIR/R6b/g || error "$DIR/R6b/g not file type"
967 }
968 run_test 24f "touch .../R6a/f R6b/g; mv .../R6a/f .../R6b/g ===="
969
970 test_24g() {
971         test_mkdir $DIR/R7a
972         test_mkdir $DIR/R7b
973         test_mkdir $DIR/R7a/d
974         mv $DIR/R7a/d $DIR/R7b/e
975         $CHECKSTAT -a $DIR/R7a/d || error "$DIR/R7a/d exists"
976         $CHECKSTAT -t dir $DIR/R7b/e || error "$DIR/R7b/e not dir type"
977 }
978 run_test 24g "mkdir .../R7{a,b}/d; mv .../R7a/d .../R7b/e ======"
979
980 test_24h() {
981         test_mkdir -c1 $DIR/R8a
982         test_mkdir -c1 $DIR/R8b
983         test_mkdir -c1 $DIR/R8a/d
984         test_mkdir -c1 $DIR/R8b/e
985         mrename $DIR/R8a/d $DIR/R8b/e
986         $CHECKSTAT -a $DIR/R8a/d || error "$DIR/R8a/d exists"
987         $CHECKSTAT -t dir $DIR/R8b/e || error "$DIR/R8b/e not dir type"
988 }
989 run_test 24h "mkdir .../R8{a,b}/{d,e}; rename .../R8a/d .../R8b/e"
990
991 test_24i() {
992         echo "-- rename error cases"
993         test_mkdir $DIR/R9
994         test_mkdir $DIR/R9/a
995         touch $DIR/R9/f
996         mrename $DIR/R9/f $DIR/R9/a
997         $CHECKSTAT -t file $DIR/R9/f || error "$DIR/R9/f not file type"
998         $CHECKSTAT -t dir  $DIR/R9/a || error "$DIR/R9/a not dir type"
999         $CHECKSTAT -a $DIR/R9/a/f || error "$DIR/R9/a/f exists"
1000 }
1001 run_test 24i "rename file to dir error: touch f ; mkdir a ; rename f a"
1002
1003 test_24j() {
1004         test_mkdir $DIR/R10
1005         mrename $DIR/R10/f $DIR/R10/g
1006         $CHECKSTAT -t dir $DIR/R10 || error "$DIR/R10 not dir type"
1007         $CHECKSTAT -a $DIR/R10/f || error "$DIR/R10/f exists"
1008         $CHECKSTAT -a $DIR/R10/g || error "$DIR/R10/g exists"
1009 }
1010 run_test 24j "source does not exist ============================"
1011
1012 test_24k() {
1013         test_mkdir $DIR/R11a
1014         test_mkdir $DIR/R11a/d
1015         touch $DIR/R11a/f
1016         mv $DIR/R11a/f $DIR/R11a/d
1017         $CHECKSTAT -a $DIR/R11a/f || error "$DIR/R11a/f exists"
1018         $CHECKSTAT -t file $DIR/R11a/d/f || error "$DIR/R11a/d/f not file type"
1019 }
1020 run_test 24k "touch .../R11a/f; mv .../R11a/f .../R11a/d ======="
1021
1022 # bug 2429 - rename foo foo foo creates invalid file
1023 test_24l() {
1024         f="$DIR/f24l"
1025         $MULTIOP $f OcNs || error "rename of ${f} to itself failed"
1026 }
1027 run_test 24l "Renaming a file to itself ========================"
1028
1029 test_24m() {
1030         f="$DIR/f24m"
1031         $MULTIOP $f OcLN ${f}2 ${f}2 || error "link ${f}2 ${f}2 failed"
1032         # on ext3 this does not remove either the source or target files
1033         # though the "expected" operation would be to remove the source
1034         $CHECKSTAT -t file ${f} || error "${f} missing"
1035         $CHECKSTAT -t file ${f}2 || error "${f}2 missing"
1036 }
1037 run_test 24m "Renaming a file to a hard link to itself ========="
1038
1039 test_24n() {
1040     f="$DIR/f24n"
1041     # this stats the old file after it was renamed, so it should fail
1042     touch ${f}
1043     $CHECKSTAT ${f} || error "${f} missing"
1044     mv ${f} ${f}.rename
1045     $CHECKSTAT ${f}.rename || error "${f}.rename missing"
1046     $CHECKSTAT -a ${f} || error "${f} exists"
1047 }
1048 run_test 24n "Statting the old file after renaming (Posix rename 2)"
1049
1050 test_24o() {
1051         test_mkdir $DIR/$tdir
1052         rename_many -s random -v -n 10 $DIR/$tdir
1053 }
1054 run_test 24o "rename of files during htree split"
1055
1056 test_24p() {
1057         test_mkdir $DIR/R12a
1058         test_mkdir $DIR/R12b
1059         DIRINO=`ls -lid $DIR/R12a | awk '{ print $1 }'`
1060         mrename $DIR/R12a $DIR/R12b
1061         $CHECKSTAT -a $DIR/R12a || error "$DIR/R12a exists"
1062         $CHECKSTAT -t dir $DIR/R12b || error "$DIR/R12b not dir type"
1063         DIRINO2=`ls -lid $DIR/R12b | awk '{ print $1 }'`
1064         [ "$DIRINO" = "$DIRINO2" ] || error "R12a $DIRINO != R12b $DIRINO2"
1065 }
1066 run_test 24p "mkdir .../R12{a,b}; rename .../R12a .../R12b"
1067
1068 cleanup_multiop_pause() {
1069         trap 0
1070         kill -USR1 $MULTIPID
1071 }
1072
1073 test_24q() {
1074         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1075
1076         test_mkdir $DIR/R13a
1077         test_mkdir $DIR/R13b
1078         local DIRINO=$(ls -lid $DIR/R13a | awk '{ print $1 }')
1079         multiop_bg_pause $DIR/R13b D_c || error "multiop failed to start"
1080         MULTIPID=$!
1081
1082         trap cleanup_multiop_pause EXIT
1083         mrename $DIR/R13a $DIR/R13b
1084         $CHECKSTAT -a $DIR/R13a || error "R13a still exists"
1085         $CHECKSTAT -t dir $DIR/R13b || error "R13b does not exist"
1086         local DIRINO2=$(ls -lid $DIR/R13b | awk '{ print $1 }')
1087         [ "$DIRINO" = "$DIRINO2" ] || error "R13a $DIRINO != R13b $DIRINO2"
1088         cleanup_multiop_pause
1089         wait $MULTIPID || error "multiop close failed"
1090 }
1091 run_test 24q "mkdir .../R13{a,b}; open R13b rename R13a R13b ==="
1092
1093 test_24r() { #bug 3789
1094         test_mkdir $DIR/R14a
1095         test_mkdir $DIR/R14a/b
1096         mrename $DIR/R14a $DIR/R14a/b && error "rename to subdir worked!"
1097         $CHECKSTAT -t dir $DIR/R14a || error "$DIR/R14a missing"
1098         $CHECKSTAT -t dir $DIR/R14a/b || error "$DIR/R14a/b missing"
1099 }
1100 run_test 24r "mkdir .../R14a/b; rename .../R14a .../R14a/b ====="
1101
1102 test_24s() {
1103         test_mkdir $DIR/R15a
1104         test_mkdir $DIR/R15a/b
1105         test_mkdir $DIR/R15a/b/c
1106         mrename $DIR/R15a $DIR/R15a/b/c && error "rename to sub-subdir worked!"
1107         $CHECKSTAT -t dir $DIR/R15a || error "$DIR/R15a missing"
1108         $CHECKSTAT -t dir $DIR/R15a/b/c || error "$DIR/R15a/b/c missing"
1109 }
1110 run_test 24s "mkdir .../R15a/b/c; rename .../R15a .../R15a/b/c ="
1111 test_24t() {
1112         test_mkdir $DIR/R16a
1113         test_mkdir $DIR/R16a/b
1114         test_mkdir $DIR/R16a/b/c
1115         mrename $DIR/R16a/b/c $DIR/R16a && error "rename to sub-subdir worked!"
1116         $CHECKSTAT -t dir $DIR/R16a || error "$DIR/R16a missing"
1117         $CHECKSTAT -t dir $DIR/R16a/b/c || error "$DIR/R16a/b/c missing"
1118 }
1119 run_test 24t "mkdir .../R16a/b/c; rename .../R16a/b/c .../R16a ="
1120
1121 test_24u() { # bug12192
1122         $MULTIOP $DIR/$tfile C2w$((2048 * 1024))c || error "multiop failed"
1123         $CHECKSTAT -s $((2048 * 1024)) $DIR/$tfile || error "wrong file size"
1124 }
1125 run_test 24u "create stripe file"
1126
1127 simple_cleanup_common() {
1128         local rc=0
1129         trap 0
1130         [ -z "$DIR" ] || [ -z "$tdir" ] && return 0
1131
1132         local start=$SECONDS
1133         rm -rf $DIR/$tdir
1134         rc=$?
1135         wait_delete_completed
1136         echo "cleanup time $((SECONDS - start))"
1137         return $rc
1138 }
1139
1140 max_pages_per_rpc() {
1141         local mdtname="$(printf "MDT%04x" ${1:-0})"
1142         $LCTL get_param -n mdc.*$mdtname*.max_pages_per_rpc
1143 }
1144
1145 test_24v() {
1146         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1147
1148         local nrfiles=${COUNT:-100000}
1149         local fname="$DIR/$tdir/$tfile"
1150
1151         # Performance issue on ZFS see LU-4072 (c.f. LU-2887)
1152         [ "$mds1_FSTYPE" = "zfs" ] && nrfiles=${COUNT:-10000}
1153
1154         test_mkdir "$(dirname $fname)"
1155         # assume MDT0000 has the fewest inodes
1156         local stripes=$($LFS getdirstripe -c $(dirname $fname))
1157         local free_inodes=$(($(mdt_free_inodes 0) * stripes))
1158         [[ $free_inodes -lt $nrfiles ]] && nrfiles=$free_inodes
1159
1160         trap simple_cleanup_common EXIT
1161
1162         createmany -m "$fname" $nrfiles
1163
1164         cancel_lru_locks mdc
1165         lctl set_param mdc.*.stats clear
1166
1167         # was previously test_24D: LU-6101
1168         # readdir() returns correct number of entries after cursor reload
1169         local num_ls=$(ls $DIR/$tdir | wc -l)
1170         local num_uniq=$(ls $DIR/$tdir | sort -u | wc -l)
1171         local num_all=$(ls -a $DIR/$tdir | wc -l)
1172         if [ $num_ls -ne $nrfiles ] || [ $num_uniq -ne $nrfiles ] ||
1173                 [ $num_all -ne $((nrfiles + 2)) ]; then
1174                         error "Expected $nrfiles files, got $num_ls " \
1175                                 "($num_uniq unique $num_all .&..)"
1176         fi
1177         # LU-5 large readdir
1178         # dirent_size = 32 bytes for sizeof(struct lu_dirent) +
1179         #               N bytes for name (len($nrfiles) rounded to 8 bytes) +
1180         #               8 bytes for luda_type (4 bytes rounded to 8 bytes)
1181         # take into account of overhead in lu_dirpage header and end mark in
1182         # each page, plus one in rpc_num calculation.
1183         local dirent_size=$((32 + (${#tfile} | 7) + 1 + 8))
1184         local page_entries=$(((PAGE_SIZE - 24) / dirent_size))
1185         local mdt_idx=$($LFS getdirstripe -i $(dirname $fname))
1186         local rpc_pages=$(max_pages_per_rpc $mdt_idx)
1187         local rpc_max=$((nrfiles / (page_entries * rpc_pages) + stripes))
1188         local mds_readpage=$(calc_stats mdc.*.stats mds_readpage)
1189         echo "readpages: $mds_readpage rpc_max: $rpc_max"
1190         (( $mds_readpage < $rpc_max - 2 || $mds_readpage > $rpc_max + 1)) &&
1191                 error "large readdir doesn't take effect: " \
1192                       "$mds_readpage should be about $rpc_max"
1193
1194         simple_cleanup_common
1195 }
1196 run_test 24v "list large directory (test hash collision, b=17560)"
1197
1198 test_24w() { # bug21506
1199         SZ1=234852
1200         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=4096 || return 1
1201         dd if=/dev/zero bs=$SZ1 count=1 >> $DIR/$tfile || return 2
1202         dd if=$DIR/$tfile of=$DIR/${tfile}_left bs=1M skip=4097 || return 3
1203         SZ2=`ls -l $DIR/${tfile}_left | awk '{print $5}'`
1204         [[ "$SZ1" -eq "$SZ2" ]] ||
1205                 error "Error reading at the end of the file $tfile"
1206 }
1207 run_test 24w "Reading a file larger than 4Gb"
1208
1209 test_24x() {
1210         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1211         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1212         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1213                 skip "Need MDS version at least 2.7.56"
1214
1215         local MDTIDX=1
1216         local remote_dir=$DIR/$tdir/remote_dir
1217
1218         test_mkdir $DIR/$tdir
1219         $LFS mkdir -i $MDTIDX $remote_dir ||
1220                 error "create remote directory failed"
1221
1222         test_mkdir $DIR/$tdir/src_dir
1223         touch $DIR/$tdir/src_file
1224         test_mkdir $remote_dir/tgt_dir
1225         touch $remote_dir/tgt_file
1226
1227         mrename $DIR/$tdir/src_dir $remote_dir/tgt_dir ||
1228                 error "rename dir cross MDT failed!"
1229
1230         mrename $DIR/$tdir/src_file $remote_dir/tgt_file ||
1231                 error "rename file cross MDT failed!"
1232
1233         touch $DIR/$tdir/ln_file
1234         ln $DIR/$tdir/ln_file $remote_dir/ln_name ||
1235                 error "ln file cross MDT failed"
1236
1237         rm -rf $DIR/$tdir || error "Can not delete directories"
1238 }
1239 run_test 24x "cross MDT rename/link"
1240
1241 test_24y() {
1242         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1243         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1244
1245         local remote_dir=$DIR/$tdir/remote_dir
1246         local mdtidx=1
1247
1248         test_mkdir $DIR/$tdir
1249         $LFS mkdir -i $mdtidx $remote_dir ||
1250                 error "create remote directory failed"
1251
1252         test_mkdir $remote_dir/src_dir
1253         touch $remote_dir/src_file
1254         test_mkdir $remote_dir/tgt_dir
1255         touch $remote_dir/tgt_file
1256
1257         mrename $remote_dir/src_dir $remote_dir/tgt_dir ||
1258                 error "rename subdir in the same remote dir failed!"
1259
1260         mrename $remote_dir/src_file $remote_dir/tgt_file ||
1261                 error "rename files in the same remote dir failed!"
1262
1263         ln $remote_dir/tgt_file $remote_dir/tgt_file1 ||
1264                 error "link files in the same remote dir failed!"
1265
1266         rm -rf $DIR/$tdir || error "Can not delete directories"
1267 }
1268 run_test 24y "rename/link on the same dir should succeed"
1269
1270 test_24z() {
1271         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
1272         [[ $MDS1_VERSION -lt $(version_code 2.12.51) ]] &&
1273                 skip "Need MDS version at least 2.12.51"
1274
1275         local index
1276
1277         for index in 0 1; do
1278                 $LFS mkdir -i $index $DIR/$tdir.$index || error "mkdir failed"
1279                 touch $DIR/$tdir.0/$tfile.$index || error "touch failed"
1280         done
1281
1282         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1 || error "mv $tfile.0 failed"
1283
1284         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.0)
1285         [ $index -eq 0 ] || error "$tfile.0 is on MDT$index"
1286
1287         local mdts=$(comma_list $(mdts_nodes))
1288
1289         do_nodes $mdts $LCTL set_param mdt.*.enable_remote_rename=0
1290         stack_trap "do_nodes $mdts $LCTL \
1291                 set_param mdt.*.enable_remote_rename=1" EXIT
1292
1293         mv $DIR/$tdir.0/$tfile.1 $DIR/$tdir.1 || error "mv $tfile.1 failed"
1294
1295         index=$($LFS getstripe -m $DIR/$tdir.1/$tfile.1)
1296         [ $index -eq 1 ] || error "$tfile.1 is on MDT$index"
1297 }
1298 run_test 24z "cross-MDT rename is done as cp"
1299
1300 test_24A() { # LU-3182
1301         local NFILES=5000
1302
1303         rm -rf $DIR/$tdir
1304         test_mkdir $DIR/$tdir
1305         trap simple_cleanup_common EXIT
1306         createmany -m $DIR/$tdir/$tfile $NFILES
1307         local t=$(ls $DIR/$tdir | wc -l)
1308         local u=$(ls $DIR/$tdir | sort -u | wc -l)
1309         local v=$(ls -ai $DIR/$tdir | sort -u | wc -l)
1310         if [ $t -ne $NFILES ] || [ $u -ne $NFILES ] ||
1311            [ $v -ne $((NFILES + 2)) ] ; then
1312                 error "Expected $NFILES files, got $t ($u unique $v .&..)"
1313         fi
1314
1315         simple_cleanup_common || error "Can not delete directories"
1316 }
1317 run_test 24A "readdir() returns correct number of entries."
1318
1319 test_24B() { # LU-4805
1320         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1321
1322         local count
1323
1324         test_mkdir $DIR/$tdir
1325         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
1326                 error "create striped dir failed"
1327
1328         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1329         [ $count -eq 2 ] || error "Expected 2, got $count"
1330
1331         touch $DIR/$tdir/striped_dir/a
1332
1333         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1334         [ $count -eq 3 ] || error "Expected 3, got $count"
1335
1336         touch $DIR/$tdir/striped_dir/.f
1337
1338         count=$(ls -ai $DIR/$tdir/striped_dir | wc -l)
1339         [ $count -eq 4 ] || error "Expected 4, got $count"
1340
1341         rm -rf $DIR/$tdir || error "Can not delete directories"
1342 }
1343 run_test 24B "readdir for striped dir return correct number of entries"
1344
1345 test_24C() {
1346         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
1347
1348         mkdir $DIR/$tdir
1349         mkdir $DIR/$tdir/d0
1350         mkdir $DIR/$tdir/d1
1351
1352         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/d0/striped_dir ||
1353                 error "create striped dir failed"
1354
1355         cd $DIR/$tdir/d0/striped_dir
1356
1357         local d0_ino=$(ls -i -l -a $DIR/$tdir | grep "d0" | awk '{print $1}')
1358         local d1_ino=$(ls -i -l -a $DIR/$tdir | grep "d1" | awk '{print $1}')
1359         local parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1360
1361         [ "$d0_ino" = "$parent_ino" ] ||
1362                 error ".. wrong, expect $d0_ino, get $parent_ino"
1363
1364         mv $DIR/$tdir/d0/striped_dir $DIR/$tdir/d1/ ||
1365                 error "mv striped dir failed"
1366
1367         parent_ino=$(ls -i -l -a | grep "\.\." | awk '{print $1}')
1368
1369         [ "$d1_ino" = "$parent_ino" ] ||
1370                 error ".. wrong after mv, expect $d1_ino, get $parent_ino"
1371 }
1372 run_test 24C "check .. in striped dir"
1373
1374 test_24E() {
1375         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
1376         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1377
1378         mkdir -p $DIR/$tdir
1379         mkdir $DIR/$tdir/src_dir
1380         $LFS mkdir -i 1 $DIR/$tdir/src_dir/src_child ||
1381                 error "create remote source failed"
1382
1383         touch $DIR/$tdir/src_dir/src_child/a
1384
1385         $LFS mkdir -i 2 $DIR/$tdir/tgt_dir ||
1386                 error "create remote target dir failed"
1387
1388         $LFS mkdir -i 3 $DIR/$tdir/tgt_dir/tgt_child ||
1389                 error "create remote target child failed"
1390
1391         mrename $DIR/$tdir/src_dir/src_child $DIR/$tdir/tgt_dir/tgt_child ||
1392                 error "rename dir cross MDT failed!"
1393
1394         find $DIR/$tdir
1395
1396         $CHECKSTAT -t dir $DIR/$tdir/src_dir/src_child &&
1397                 error "src_child still exists after rename"
1398
1399         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/tgt_child/a ||
1400                 error "missing file(a) after rename"
1401
1402         rm -rf $DIR/$tdir || error "Can not delete directories"
1403 }
1404 run_test 24E "cross MDT rename/link"
1405
1406 test_24F () {
1407         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
1408
1409         local repeats=1000
1410         [ "$SLOW" = "no" ] && repeats=100
1411
1412         mkdir -p $DIR/$tdir
1413
1414         echo "$repeats repeats"
1415         for ((i = 0; i < repeats; i++)); do
1416                 $LFS mkdir -i0 -c2 $DIR/$tdir/test || error "mkdir fails"
1417                 touch $DIR/$tdir/test/a || error "touch fails"
1418                 mkdir $DIR/$tdir/test/b || error "mkdir fails"
1419                 rm -rf $DIR/$tdir/test || error "rmdir fails"
1420         done
1421
1422         true
1423 }
1424 run_test 24F "hash order vs readdir (LU-11330)"
1425
1426 test_25a() {
1427         echo '== symlink sanity ============================================='
1428
1429         test_mkdir $DIR/d25
1430         ln -s d25 $DIR/s25
1431         touch $DIR/s25/foo ||
1432                 error "File creation in symlinked directory failed"
1433 }
1434 run_test 25a "create file in symlinked directory ==============="
1435
1436 test_25b() {
1437         [ ! -d $DIR/d25 ] && test_25a
1438         $CHECKSTAT -t file $DIR/s25/foo || error "$DIR/s25/foo not file type"
1439 }
1440 run_test 25b "lookup file in symlinked directory ==============="
1441
1442 test_26a() {
1443         test_mkdir $DIR/d26
1444         test_mkdir $DIR/d26/d26-2
1445         ln -s d26/d26-2 $DIR/s26
1446         touch $DIR/s26/foo || error "File creation failed"
1447 }
1448 run_test 26a "multiple component symlink ======================="
1449
1450 test_26b() {
1451         test_mkdir -p $DIR/$tdir/d26-2
1452         ln -s $tdir/d26-2/foo $DIR/s26-2
1453         touch $DIR/s26-2 || error "File creation failed"
1454 }
1455 run_test 26b "multiple component symlink at end of lookup ======"
1456
1457 test_26c() {
1458         test_mkdir $DIR/d26.2
1459         touch $DIR/d26.2/foo
1460         ln -s d26.2 $DIR/s26.2-1
1461         ln -s s26.2-1 $DIR/s26.2-2
1462         ln -s s26.2-2 $DIR/s26.2-3
1463         chmod 0666 $DIR/s26.2-3/foo
1464 }
1465 run_test 26c "chain of symlinks"
1466
1467 # recursive symlinks (bug 439)
1468 test_26d() {
1469         ln -s d26-3/foo $DIR/d26-3
1470 }
1471 run_test 26d "create multiple component recursive symlink"
1472
1473 test_26e() {
1474         [ ! -h $DIR/d26-3 ] && test_26d
1475         rm $DIR/d26-3
1476 }
1477 run_test 26e "unlink multiple component recursive symlink"
1478
1479 # recursive symlinks (bug 7022)
1480 test_26f() {
1481         test_mkdir $DIR/$tdir
1482         test_mkdir $DIR/$tdir/$tfile
1483         cd $DIR/$tdir/$tfile           || error "cd $DIR/$tdir/$tfile failed"
1484         test_mkdir -p lndir/bar1
1485         test_mkdir $DIR/$tdir/$tfile/$tfile
1486         cd $tfile                || error "cd $tfile failed"
1487         ln -s .. dotdot          || error "ln dotdot failed"
1488         ln -s dotdot/lndir lndir || error "ln lndir failed"
1489         cd $DIR/$tdir                 || error "cd $DIR/$tdir failed"
1490         output=`ls $tfile/$tfile/lndir/bar1`
1491         [ "$output" = bar1 ] && error "unexpected output"
1492         rm -r $tfile             || error "rm $tfile failed"
1493         $CHECKSTAT -a $DIR/$tfile || error "$tfile not gone"
1494 }
1495 run_test 26f "rm -r of a directory which has recursive symlink"
1496
1497 test_27a() {
1498         test_mkdir $DIR/$tdir
1499         $LFS getstripe $DIR/$tdir
1500         $LFS setstripe -c 1 $DIR/$tdir/$tfile || error "setstripe failed"
1501         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1502         cp /etc/hosts $DIR/$tdir/$tfile || error "Can't copy to one stripe file"
1503 }
1504 run_test 27a "one stripe file"
1505
1506 test_27b() {
1507         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1508
1509         test_mkdir $DIR/$tdir
1510         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1511         $LFS getstripe -c $DIR/$tdir/$tfile
1512         [ $($LFS getstripe -c $DIR/$tdir/$tfile) -eq 2 ] ||
1513                 error "two-stripe file doesn't have two stripes"
1514
1515         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1516 }
1517 run_test 27b "create and write to two stripe file"
1518
1519 # 27c family tests specific striping, setstripe -o
1520 test_27ca() {
1521         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1522         test_mkdir -p $DIR/$tdir
1523         local osts="1"
1524
1525         $LFS setstripe -o $osts $DIR/$tdir/$tfile  || error "setstripe failed"
1526         $LFS getstripe -i $DIR/$tdir/$tfile
1527         [ $($LFS getstripe -i $DIR/$tdir/$tfile ) -eq $osts ] ||
1528                 error "stripe not on specified OST"
1529
1530         dd if=/dev/zero of=$DIR/$tdir/$tfile  bs=1M count=4 || error "dd failed"
1531 }
1532 run_test 27ca "one stripe on specified OST"
1533
1534 test_27cb() {
1535         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1536         test_mkdir -p $DIR/$tdir
1537         local osts="1,0"
1538         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1539         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1540         echo "$getstripe"
1541
1542         # Strip getstripe output to a space separated list of OSTs
1543         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1544                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1545         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1546                 error "stripes not on specified OSTs"
1547
1548         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1549 }
1550 run_test 27cb "two stripes on specified OSTs"
1551
1552 test_27cc() {
1553         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1554         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1555                 skip "server does not support overstriping"
1556
1557         test_mkdir -p $DIR/$tdir
1558         local osts="0,0"
1559         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1560         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1561         echo "$getstripe"
1562
1563         # Strip getstripe output to a space separated list of OSTs
1564         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1565                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1566         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1567                 error "stripes not on specified OSTs"
1568
1569         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1570 }
1571 run_test 27cc "two stripes on the same OST"
1572
1573 test_27cd() {
1574         [[ $OSTCOUNT -lt 2 ]] && skip_env "skipping 2-stripe test"
1575         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1576                 skip "server does not support overstriping"
1577         test_mkdir -p $DIR/$tdir
1578         local osts="0,1,1,0"
1579         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1580         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1581         echo "$getstripe"
1582
1583         # Strip getstripe output to a space separated list of OSTs
1584         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1585                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1586         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1587                 error "stripes not on specified OSTs"
1588
1589         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1590 }
1591 run_test 27cd "four stripes on two OSTs"
1592
1593 test_27ce() {
1594         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
1595                 skip_env "too many osts, skipping"
1596         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
1597                 skip "server does not support overstriping"
1598         # We do one more stripe than we have OSTs
1599         [ $OSTCOUNT -ge 159 ] || large_xattr_enabled ||
1600                 skip_env "ea_inode feature disabled"
1601
1602         test_mkdir -p $DIR/$tdir
1603         local osts=""
1604         for i in $(seq 0 $OSTCOUNT);
1605         do
1606                 osts=$osts"0"
1607                 if [ $i -ne $OSTCOUNT ]; then
1608                         osts=$osts","
1609                 fi
1610         done
1611         $LFS setstripe -o $osts $DIR/$tdir/$tfile || error "setstripe failed"
1612         local getstripe=$($LFS getstripe $DIR/$tdir/$tfile)
1613         echo "$getstripe"
1614
1615         # Strip getstripe output to a space separated list of OSTs
1616         local getstripe_osts=$(echo "$getstripe" | sed -e '1,/obdidx/d' |\
1617                 awk '{print $1}' | tr '\n' '\ ' | sed -e 's/[[:space:]]*$//')
1618         [ "$getstripe_osts" = "${osts//,/ }" ] ||
1619                 error "stripes not on specified OSTs"
1620
1621         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 || error "dd failed"
1622 }
1623 run_test 27ce "more stripes than OSTs with -o"
1624
1625 test_27d() {
1626         test_mkdir $DIR/$tdir
1627         $LFS setstripe -c 0 -i -1 -S 0 $DIR/$tdir/$tfile ||
1628                 error "setstripe failed"
1629         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1630         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1631 }
1632 run_test 27d "create file with default settings"
1633
1634 test_27e() {
1635         # LU-5839 adds check for existed layout before setting it
1636         [[ $MDS1_VERSION -lt $(version_code 2.7.56) ]] &&
1637                 skip "Need MDS version at least 2.7.56"
1638
1639         test_mkdir $DIR/$tdir
1640         $LFS setstripe -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1641         $LFS setstripe -c 2 $DIR/$tdir/$tfile && error "setstripe worked twice"
1642         $CHECKSTAT -t file $DIR/$tdir/$tfile || error "checkstat failed"
1643 }
1644 run_test 27e "setstripe existing file (should return error)"
1645
1646 test_27f() {
1647         test_mkdir $DIR/$tdir
1648         $LFS setstripe -S 100 -i 0 -c 1 $DIR/$tdir/$tfile &&
1649                 error "$LFS setstripe $DIR/$tdir/$tfile failed"
1650         $CHECKSTAT -t file $DIR/$tdir/$tfile &&
1651                 error "$CHECKSTAT -t file $DIR/$tdir/$tfile should fail"
1652         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=4k count=4 || error "dd failed"
1653         $LFS getstripe $DIR/$tdir/$tfile || error "$LFS getstripe failed"
1654 }
1655 run_test 27f "setstripe with bad stripe size (should return error)"
1656
1657 test_27g() {
1658         test_mkdir $DIR/$tdir
1659         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1660         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "no stripe info" ||
1661                 error "$DIR/$tdir/$tfile has object"
1662 }
1663 run_test 27g "$LFS getstripe with no objects"
1664
1665 test_27ga() {
1666         test_mkdir $DIR/$tdir
1667         touch $DIR/$tdir/$tfile || error "touch failed"
1668         ln -s bogus $DIR/$tdir/$tfile.2 || error "ln failed"
1669         $LFS getstripe -m $DIR/$tdir/$tfile $DIR/$tdir/$tfile.2
1670         local rc=$?
1671         (( rc == 2 )) || error "getstripe did not return ENOENT"
1672 }
1673 run_test 27ga "$LFS getstripe with missing file (should return error)"
1674
1675 test_27i() {
1676         test_mkdir $DIR/$tdir
1677         touch $DIR/$tdir/$tfile || error "touch failed"
1678         [[ $($LFS getstripe -c $DIR/$tdir/$tfile) -gt 0 ]] ||
1679                 error "missing objects"
1680 }
1681 run_test 27i "$LFS getstripe with some objects"
1682
1683 test_27j() {
1684         test_mkdir $DIR/$tdir
1685         $LFS setstripe -i $OSTCOUNT $DIR/$tdir/$tfile &&
1686                 error "setstripe failed" || true
1687 }
1688 run_test 27j "setstripe with bad stripe offset (should return error)"
1689
1690 test_27k() { # bug 2844
1691         test_mkdir $DIR/$tdir
1692         local file=$DIR/$tdir/$tfile
1693         local ll_max_blksize=$((4 * 1024 * 1024))
1694         $LFS setstripe -S 67108864 $file || error "setstripe failed"
1695         local blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1696         [ $blksize -le $ll_max_blksize ] || error "1:$blksize > $ll_max_blksize"
1697         dd if=/dev/zero of=$file bs=4k count=1
1698         blksize=$(stat $file | awk '/IO Block:/ { print $7 }')
1699         [ $blksize -le $ll_max_blksize ] || error "2:$blksize > $ll_max_blksize"
1700 }
1701 run_test 27k "limit i_blksize for broken user apps"
1702
1703 test_27l() {
1704         mcreate $DIR/$tfile || error "creating file"
1705         $RUNAS $LFS setstripe -c 1 $DIR/$tfile &&
1706                 error "setstripe should have failed" || true
1707 }
1708 run_test 27l "check setstripe permissions (should return error)"
1709
1710 test_27m() {
1711         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1712
1713         [ -n "$RCLIENTS" -o -n "$MOUNT_2" ] &&
1714                 skip_env "multiple clients -- skipping"
1715
1716         ORIGFREE=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
1717                    head -n1)
1718         if [[ $ORIGFREE -gt $MAXFREE ]]; then
1719                 skip "$ORIGFREE > $MAXFREE skipping out-of-space test on OST0"
1720         fi
1721         trap simple_cleanup_common EXIT
1722         test_mkdir $DIR/$tdir
1723         $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.1
1724         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1024 count=$MAXFREE &&
1725                 error "dd should fill OST0"
1726         i=2
1727         while $LFS setstripe -i 0 -c 1 $DIR/$tdir/$tfile.$i; do
1728                 i=$((i + 1))
1729                 [ $i -gt 256 ] && break
1730         done
1731         i=$((i + 1))
1732         touch $DIR/$tdir/$tfile.$i
1733         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1734             awk '{print $1}'| grep -w "0") ] &&
1735                 error "OST0 was full but new created file still use it"
1736         i=$((i + 1))
1737         touch $DIR/$tdir/$tfile.$i
1738         [ $($LFS getstripe $DIR/$tdir/$tfile.$i | grep -A 10 obdidx |
1739             awk '{print $1}'| grep -w "0") ] &&
1740                 error "OST0 was full but new created file still use it"
1741         simple_cleanup_common
1742 }
1743 run_test 27m "create file while OST0 was full"
1744
1745 # OSCs keep a NOSPC flag that will be reset after ~5s (qos_maxage)
1746 # if the OST isn't full anymore.
1747 reset_enospc() {
1748         local OSTIDX=${1:-""}
1749
1750         local list=$(comma_list $(osts_nodes))
1751         [ "$OSTIDX" ] && list=$(facet_host ost$((OSTIDX + 1)))
1752
1753         do_nodes $list lctl set_param fail_loc=0
1754         sync    # initiate all OST_DESTROYs from MDS to OST
1755         sleep_maxage
1756 }
1757
1758 exhaust_precreations() {
1759         local OSTIDX=$1
1760         local FAILLOC=$2
1761         local FAILIDX=${3:-$OSTIDX}
1762         local ofacet=ost$((OSTIDX + 1))
1763
1764         test_mkdir -p -c1 $DIR/$tdir
1765         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
1766         local mfacet=mds$((mdtidx + 1))
1767         echo OSTIDX=$OSTIDX MDTIDX=$mdtidx
1768
1769         local OST=$(ostname_from_index $OSTIDX)
1770
1771         # on the mdt's osc
1772         local mdtosc_proc1=$(get_mdtosc_proc_path $mfacet $OST)
1773         local last_id=$(do_facet $mfacet lctl get_param -n \
1774                         osp.$mdtosc_proc1.prealloc_last_id)
1775         local next_id=$(do_facet $mfacet lctl get_param -n \
1776                         osp.$mdtosc_proc1.prealloc_next_id)
1777
1778         local mdtosc_proc2=$(get_mdtosc_proc_path $mfacet)
1779         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1780
1781         test_mkdir -p $DIR/$tdir/${OST}
1782         $LFS setstripe -i $OSTIDX -c 1 $DIR/$tdir/${OST}
1783 #define OBD_FAIL_OST_ENOSPC              0x215
1784         do_facet $ofacet lctl set_param fail_val=$FAILIDX fail_loc=0x215
1785         echo "Creating to objid $last_id on ost $OST..."
1786         createmany -o $DIR/$tdir/${OST}/f $next_id $((last_id - next_id + 2))
1787         do_facet $mfacet lctl get_param osp.$mdtosc_proc2.prealloc*
1788         do_facet $ofacet lctl set_param fail_loc=$FAILLOC
1789         sleep_maxage
1790 }
1791
1792 exhaust_all_precreations() {
1793         local i
1794         for (( i=0; i < OSTCOUNT; i++ )) ; do
1795                 exhaust_precreations $i $1 -1
1796         done
1797 }
1798
1799 test_27n() {
1800         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1802         remote_mds_nodsh && skip "remote MDS with nodsh"
1803         remote_ost_nodsh && skip "remote OST with nodsh"
1804
1805         reset_enospc
1806         rm -f $DIR/$tdir/$tfile
1807         exhaust_precreations 0 0x80000215
1808         $LFS setstripe -c -1 $DIR/$tdir || error "setstripe failed"
1809         touch $DIR/$tdir/$tfile || error "touch failed"
1810         $LFS getstripe $DIR/$tdir/$tfile
1811         reset_enospc
1812 }
1813 run_test 27n "create file with some full OSTs"
1814
1815 test_27o() {
1816         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1818         remote_mds_nodsh && skip "remote MDS with nodsh"
1819         remote_ost_nodsh && skip "remote OST with nodsh"
1820
1821         reset_enospc
1822         rm -f $DIR/$tdir/$tfile
1823         exhaust_all_precreations 0x215
1824
1825         touch $DIR/$tdir/$tfile && error "able to create $DIR/$tdir/$tfile"
1826
1827         reset_enospc
1828         rm -rf $DIR/$tdir/*
1829 }
1830 run_test 27o "create file with all full OSTs (should error)"
1831
1832 test_27p() {
1833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1834         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1835         remote_mds_nodsh && skip "remote MDS with nodsh"
1836         remote_ost_nodsh && skip "remote OST with nodsh"
1837
1838         reset_enospc
1839         rm -f $DIR/$tdir/$tfile
1840         test_mkdir $DIR/$tdir
1841
1842         $MCREATE $DIR/$tdir/$tfile || error "mcreate failed"
1843         $TRUNCATE $DIR/$tdir/$tfile 80000000 || error "truncate failed"
1844         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1845
1846         exhaust_precreations 0 0x80000215
1847         echo foo >> $DIR/$tdir/$tfile || error "append failed"
1848         $CHECKSTAT -s 80000004 $DIR/$tdir/$tfile || error "checkstat failed"
1849         $LFS getstripe $DIR/$tdir/$tfile
1850
1851         reset_enospc
1852 }
1853 run_test 27p "append to a truncated file with some full OSTs"
1854
1855 test_27q() {
1856         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1857         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1858         remote_mds_nodsh && skip "remote MDS with nodsh"
1859         remote_ost_nodsh && skip "remote OST with nodsh"
1860
1861         reset_enospc
1862         rm -f $DIR/$tdir/$tfile
1863
1864         test_mkdir $DIR/$tdir
1865         $MCREATE $DIR/$tdir/$tfile || error "mcreate $DIR/$tdir/$tfile failed"
1866         $TRUNCATE $DIR/$tdir/$tfile 80000000 ||
1867                 error "truncate $DIR/$tdir/$tfile failed"
1868         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat failed"
1869
1870         exhaust_all_precreations 0x215
1871
1872         echo foo >> $DIR/$tdir/$tfile && error "append succeeded"
1873         $CHECKSTAT -s 80000000 $DIR/$tdir/$tfile || error "checkstat 2 failed"
1874
1875         reset_enospc
1876 }
1877 run_test 27q "append to truncated file with all OSTs full (should error)"
1878
1879 test_27r() {
1880         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1881         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1882         remote_mds_nodsh && skip "remote MDS with nodsh"
1883         remote_ost_nodsh && skip "remote OST with nodsh"
1884
1885         reset_enospc
1886         rm -f $DIR/$tdir/$tfile
1887         exhaust_precreations 0 0x80000215
1888
1889         $LFS setstripe -i 0 -c 2 $DIR/$tdir/$tfile || error "setstripe failed"
1890
1891         reset_enospc
1892 }
1893 run_test 27r "stripe file with some full OSTs (shouldn't LBUG) ="
1894
1895 test_27s() { # bug 10725
1896         test_mkdir $DIR/$tdir
1897         local stripe_size=$((4096 * 1024 * 1024))       # 2^32
1898         local stripe_count=0
1899         [ $OSTCOUNT -eq 1 ] || stripe_count=2
1900         $LFS setstripe -S $stripe_size -c $stripe_count $DIR/$tdir &&
1901                 error "stripe width >= 2^32 succeeded" || true
1902
1903 }
1904 run_test 27s "lsm_xfersize overflow (should error) (bug 10725)"
1905
1906 test_27t() { # bug 10864
1907         WDIR=$(pwd)
1908         WLFS=$(which lfs)
1909         cd $DIR
1910         touch $tfile
1911         $WLFS getstripe $tfile
1912         cd $WDIR
1913 }
1914 run_test 27t "check that utils parse path correctly"
1915
1916 test_27u() { # bug 4900
1917         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1918         remote_mds_nodsh && skip "remote MDS with nodsh"
1919
1920         local index
1921         local list=$(comma_list $(mdts_nodes))
1922
1923 #define OBD_FAIL_MDS_OSC_PRECREATE      0x139
1924         do_nodes $list $LCTL set_param fail_loc=0x139
1925         test_mkdir -p $DIR/$tdir
1926         trap simple_cleanup_common EXIT
1927         createmany -o $DIR/$tdir/t- 1000
1928         do_nodes $list $LCTL set_param fail_loc=0
1929
1930         TLOG=$TMP/$tfile.getstripe
1931         $LFS getstripe $DIR/$tdir > $TLOG
1932         OBJS=$(awk -vobj=0 '($1 == 0) { obj += 1 } END { print obj; }' $TLOG)
1933         unlinkmany $DIR/$tdir/t- 1000
1934         trap 0
1935         [[ $OBJS -gt 0 ]] &&
1936                 error "$OBJS objects created on OST-0. See $TLOG" ||
1937                 rm -f $TLOG
1938 }
1939 run_test 27u "skip object creation on OSC w/o objects"
1940
1941 test_27v() { # bug 4900
1942         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
1943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
1944         remote_mds_nodsh && skip "remote MDS with nodsh"
1945         remote_ost_nodsh && skip "remote OST with nodsh"
1946
1947         exhaust_all_precreations 0x215
1948         reset_enospc
1949
1950         $LFS setstripe -c 1 $DIR/$tdir         # 1 stripe / file
1951
1952         touch $DIR/$tdir/$tfile
1953         #define OBD_FAIL_TGT_DELAY_PRECREATE     0x705
1954         # all except ost1
1955         for (( i=1; i < OSTCOUNT; i++ )); do
1956                 do_facet ost$i lctl set_param fail_loc=0x705
1957         done
1958         local START=`date +%s`
1959         createmany -o $DIR/$tdir/$tfile 32
1960
1961         local FINISH=`date +%s`
1962         local TIMEOUT=`lctl get_param -n timeout`
1963         local PROCESS=$((FINISH - START))
1964         [ $PROCESS -ge $((TIMEOUT / 2)) ] && \
1965                error "$FINISH - $START >= $TIMEOUT / 2"
1966         sleep $((TIMEOUT / 2 - PROCESS))
1967         reset_enospc
1968 }
1969 run_test 27v "skip object creation on slow OST"
1970
1971 test_27w() { # bug 10997
1972         test_mkdir $DIR/$tdir
1973         $LFS setstripe -S 65536 $DIR/$tdir/f0 || error "setstripe failed"
1974         [ $($LFS getstripe -S $DIR/$tdir/f0) -ne 65536 ] &&
1975                 error "stripe size $size != 65536" || true
1976         [ $($LFS getstripe -d $DIR/$tdir | grep -c "stripe_count") -eq 0 ] &&
1977                 error "$LFS getstripe -d $DIR/$tdir no 'stripe_count'" || true
1978 }
1979 run_test 27w "check $LFS setstripe -S and getstrip -d options"
1980
1981 test_27wa() {
1982         [[ $OSTCOUNT -lt 2 ]] &&
1983                 skip_env "skipping multiple stripe count/offset test"
1984
1985         test_mkdir $DIR/$tdir
1986         for i in $(seq 1 $OSTCOUNT); do
1987                 offset=$((i - 1))
1988                 $LFS setstripe -c $i -i $offset $DIR/$tdir/f$i ||
1989                         error "setstripe -c $i -i $offset failed"
1990                 count=$($LFS getstripe -c $DIR/$tdir/f$i)
1991                 index=$($LFS getstripe -i $DIR/$tdir/f$i)
1992                 [ $count -ne $i ] && error "stripe count $count != $i" || true
1993                 [ $index -ne $offset ] &&
1994                         error "stripe offset $index != $offset" || true
1995         done
1996 }
1997 run_test 27wa "check $LFS setstripe -c -i options"
1998
1999 test_27x() {
2000         remote_ost_nodsh && skip "remote OST with nodsh"
2001         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2003
2004         OFFSET=$(($OSTCOUNT - 1))
2005         OSTIDX=0
2006         local OST=$(ostname_from_index $OSTIDX)
2007
2008         test_mkdir $DIR/$tdir
2009         $LFS setstripe -c 1 $DIR/$tdir  # 1 stripe per file
2010         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 1
2011         sleep_maxage
2012         createmany -o $DIR/$tdir/$tfile $OSTCOUNT
2013         for i in $(seq 0 $OFFSET); do
2014                 [ $($LFS getstripe $DIR/$tdir/$tfile$i | grep -A 10 obdidx |
2015                         awk '{print $1}' | grep -w "$OSTIDX") ] &&
2016                 error "OST0 was degraded but new created file still use it"
2017         done
2018         do_facet ost$((OSTIDX + 1)) lctl set_param -n obdfilter.$OST.degraded 0
2019 }
2020 run_test 27x "create files while OST0 is degraded"
2021
2022 test_27y() {
2023         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2024         remote_mds_nodsh && skip "remote MDS with nodsh"
2025         remote_ost_nodsh && skip "remote OST with nodsh"
2026         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2027
2028         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS $FSNAME-OST0000)
2029         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
2030                 osp.$mdtosc.prealloc_last_id)
2031         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
2032                 osp.$mdtosc.prealloc_next_id)
2033         local fcount=$((last_id - next_id))
2034         [[ $fcount -eq 0 ]] && skip "not enough space on OST0"
2035         [[ $fcount -gt $OSTCOUNT ]] && fcount=$OSTCOUNT
2036
2037         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
2038                          awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
2039         local OST_DEACTIVE_IDX=-1
2040         local OSC
2041         local OSTIDX
2042         local OST
2043
2044         for OSC in $MDS_OSCS; do
2045                 OST=$(osc_to_ost $OSC)
2046                 OSTIDX=$(index_from_ostuuid $OST)
2047                 if [ $OST_DEACTIVE_IDX == -1 ]; then
2048                         OST_DEACTIVE_IDX=$OSTIDX
2049                 fi
2050                 if [ $OSTIDX != $OST_DEACTIVE_IDX ]; then
2051                         echo $OSC "is Deactivated:"
2052                         do_facet $SINGLEMDS lctl --device  %$OSC deactivate
2053                 fi
2054         done
2055
2056         OSTIDX=$(index_from_ostuuid $OST)
2057         test_mkdir $DIR/$tdir
2058         $LFS setstripe -c 1 $DIR/$tdir      # 1 stripe / file
2059
2060         for OSC in $MDS_OSCS; do
2061                 OST=$(osc_to_ost $OSC)
2062                 OSTIDX=$(index_from_ostuuid $OST)
2063                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2064                         echo $OST "is degraded:"
2065                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2066                                                 obdfilter.$OST.degraded=1
2067                 fi
2068         done
2069
2070         sleep_maxage
2071         createmany -o $DIR/$tdir/$tfile $fcount
2072
2073         for OSC in $MDS_OSCS; do
2074                 OST=$(osc_to_ost $OSC)
2075                 OSTIDX=$(index_from_ostuuid $OST)
2076                 if [ $OSTIDX == $OST_DEACTIVE_IDX ]; then
2077                         echo $OST "is recovered from degraded:"
2078                         do_facet ost$((OSTIDX+1)) lctl set_param -n \
2079                                                 obdfilter.$OST.degraded=0
2080                 else
2081                         do_facet $SINGLEMDS lctl --device %$OSC activate
2082                 fi
2083         done
2084
2085         # all osp devices get activated, hence -1 stripe count restored
2086         local stripe_count=0
2087
2088         # sleep 2*lod_qos_maxage seconds waiting for lod qos to notice osp
2089         # devices get activated.
2090         sleep_maxage
2091         $LFS setstripe -c -1 $DIR/$tfile
2092         stripe_count=$($LFS getstripe -c $DIR/$tfile)
2093         rm -f $DIR/$tfile
2094         [ $stripe_count -ne $OSTCOUNT ] &&
2095                 error "Of $OSTCOUNT OSTs, only $stripe_count is available"
2096         return 0
2097 }
2098 run_test 27y "create files while OST0 is degraded and the rest inactive"
2099
2100 check_seq_oid()
2101 {
2102         log "check file $1"
2103
2104         lmm_count=$($LFS getstripe -c $1)
2105         lmm_seq=$($LFS getstripe -v $1 | awk '/lmm_seq/ { print $2 }')
2106         lmm_oid=$($LFS getstripe -v $1 | awk '/lmm_object_id/ { print $2 }')
2107
2108         local old_ifs="$IFS"
2109         IFS=$'[:]'
2110         fid=($($LFS path2fid $1))
2111         IFS="$old_ifs"
2112
2113         log "FID seq ${fid[1]}, oid ${fid[2]} ver ${fid[3]}"
2114         log "LOV seq $lmm_seq, oid $lmm_oid, count: $lmm_count"
2115
2116         # compare lmm_seq and lu_fid->f_seq
2117         [ $lmm_seq = ${fid[1]} ] || { error "SEQ mismatch"; return 1; }
2118         # compare lmm_object_id and lu_fid->oid
2119         [ $lmm_oid = ${fid[2]} ] || { error "OID mismatch"; return 2; }
2120
2121         # check the trusted.fid attribute of the OST objects of the file
2122         local have_obdidx=false
2123         local stripe_nr=0
2124         $LFS getstripe $1 | while read obdidx oid hex seq; do
2125                 # skip lines up to and including "obdidx"
2126                 [ -z "$obdidx" ] && break
2127                 [ "$obdidx" = "obdidx" ] && have_obdidx=true && continue
2128                 $have_obdidx || continue
2129
2130                 local ost=$((obdidx + 1))
2131                 local dev=$(ostdevname $ost)
2132                 local oid_hex
2133
2134                 log "want: stripe:$stripe_nr ost:$obdidx oid:$oid/$hex seq:$seq"
2135
2136                 seq=$(echo $seq | sed -e "s/^0x//g")
2137                 if [ $seq == 0 ] || [ $(facet_fstype ost$ost) == zfs ]; then
2138                         oid_hex=$(echo $oid)
2139                 else
2140                         oid_hex=$(echo $hex | sed -e "s/^0x//g")
2141                 fi
2142                 local obj_file="O/$seq/d$((oid %32))/$oid_hex"
2143
2144                 local ff=""
2145                 #
2146                 # Don't unmount/remount the OSTs if we don't need to do that.
2147                 # LU-2577 changes filter_fid to be smaller, so debugfs needs
2148                 # update too, until that use mount/ll_decode_filter_fid/mount.
2149                 # Re-enable when debugfs will understand new filter_fid.
2150                 #
2151                 if [ $(facet_fstype ost$ost) == ldiskfs ]; then
2152                         ff=$(do_facet ost$ost "$DEBUGFS -c -R 'stat $obj_file' \
2153                                 $dev 2>/dev/null" | grep "parent=")
2154                 fi
2155                 if [ -z "$ff" ]; then
2156                         stop ost$ost
2157                         mount_fstype ost$ost
2158                         ff=$(do_facet ost$ost $LL_DECODE_FILTER_FID \
2159                                 $(facet_mntpt ost$ost)/$obj_file)
2160                         unmount_fstype ost$ost
2161                         start ost$ost $dev $OST_MOUNT_OPTS
2162                         clients_up
2163                 fi
2164
2165                 [ -z "$ff" ] && error "$obj_file: no filter_fid info"
2166
2167                 echo "$ff" | sed -e 's#.*objid=#got: objid=#'
2168
2169                 # /mnt/O/0/d23/23: objid=23 seq=0 parent=[0x200000400:0x1e:0x1]
2170                 # fid: objid=23 seq=0 parent=[0x200000400:0x1e:0x0] stripe=1
2171                 #
2172                 # fid: parent=[0x200000400:0x1e:0x0] stripe=1 stripe_count=2 \
2173                 #       stripe_size=1048576 component_id=1 component_start=0 \
2174                 #       component_end=33554432
2175                 local ff_parent=$(sed -e 's/.*parent=.//' <<<$ff)
2176                 local ff_pseq=$(cut -d: -f1 <<<$ff_parent)
2177                 local ff_poid=$(cut -d: -f2 <<<$ff_parent)
2178                 local ff_pstripe
2179                 if grep -q 'stripe=' <<<$ff; then
2180                         ff_pstripe=$(sed -e 's/.*stripe=//' -e 's/ .*//' <<<$ff)
2181                 else
2182                         # $LL_DECODE_FILTER_FID does not print "stripe="; look
2183                         # into f_ver in this case.  See comment on ff_parent.
2184                         ff_pstripe=$(cut -d: -f3 <<<$ff_parent | sed -e 's/]//')
2185                 fi
2186
2187                 # compare lmm_seq and filter_fid->ff_parent.f_seq
2188                 [ $ff_pseq = $lmm_seq ] ||
2189                         error "FF parent SEQ $ff_pseq != $lmm_seq"
2190                 # compare lmm_object_id and filter_fid->ff_parent.f_oid
2191                 [ $ff_poid = $lmm_oid ] ||
2192                         error "FF parent OID $ff_poid != $lmm_oid"
2193                 (($ff_pstripe == $stripe_nr)) ||
2194                         error "FF stripe $ff_pstripe != $stripe_nr"
2195
2196                 stripe_nr=$((stripe_nr + 1))
2197                 [ $CLIENT_VERSION -lt $(version_code 2.9.55) ] &&
2198                         continue
2199                 if grep -q 'stripe_count=' <<<$ff; then
2200                         local ff_scnt=$(sed -e 's/.*stripe_count=//' \
2201                                             -e 's/ .*//' <<<$ff)
2202                         [ $lmm_count = $ff_scnt ] ||
2203                                 error "FF stripe count $lmm_count != $ff_scnt"
2204                 fi
2205         done
2206 }
2207
2208 test_27z() {
2209         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2210         remote_ost_nodsh && skip "remote OST with nodsh"
2211
2212         test_mkdir $DIR/$tdir
2213         $LFS setstripe -c 1 -i 0 -S 64k $DIR/$tdir/$tfile-1 ||
2214                 { error "setstripe -c -1 failed"; return 1; }
2215         # We need to send a write to every object to get parent FID info set.
2216         # This _should_ also work for setattr, but does not currently.
2217         # touch $DIR/$tdir/$tfile-1 ||
2218         dd if=/dev/zero of=$DIR/$tdir/$tfile-1 bs=1M count=1 ||
2219                 { error "dd $tfile-1 failed"; return 2; }
2220         $LFS setstripe -c -1 -i $((OSTCOUNT - 1)) -S 1M $DIR/$tdir/$tfile-2 ||
2221                 { error "setstripe -c -1 failed"; return 3; }
2222         dd if=/dev/zero of=$DIR/$tdir/$tfile-2 bs=1M count=$OSTCOUNT ||
2223                 { error "dd $tfile-2 failed"; return 4; }
2224
2225         # make sure write RPCs have been sent to OSTs
2226         sync; sleep 5; sync
2227
2228         check_seq_oid $DIR/$tdir/$tfile-1 || return 5
2229         check_seq_oid $DIR/$tdir/$tfile-2 || return 6
2230 }
2231 run_test 27z "check SEQ/OID on the MDT and OST filesystems"
2232
2233 test_27A() { # b=19102
2234         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2235
2236         save_layout_restore_at_exit $MOUNT
2237         $LFS setstripe -c 0 -i -1 -S 0 $MOUNT
2238         wait_update $HOSTNAME "$LFS getstripe -c $MOUNT | sed 's/  *//g'" "1" 20 ||
2239                 error "stripe count $($LFS getstripe -c $MOUNT) != 1"
2240         local default_size=$($LFS getstripe -S $MOUNT)
2241         local default_offset=$($LFS getstripe -i $MOUNT)
2242         local dsize=$(do_facet $SINGLEMDS \
2243                 "$LCTL get_param -n lod.$(facet_svc $SINGLEMDS)*.stripesize")
2244         [ $default_size -eq $dsize ] ||
2245                 error "stripe size $default_size != $dsize"
2246         [ $default_offset -eq -1 ] ||
2247                 error "stripe offset $default_offset != -1"
2248 }
2249 run_test 27A "check filesystem-wide default LOV EA values"
2250
2251 test_27B() { # LU-2523
2252         test_mkdir $DIR/$tdir
2253         rm -f $DIR/$tdir/f0 $DIR/$tdir/f1
2254         touch $DIR/$tdir/f0
2255         # open f1 with O_LOV_DELAY_CREATE
2256         # rename f0 onto f1
2257         # call setstripe ioctl on open file descriptor for f1
2258         # close
2259         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:nB1c \
2260                 $DIR/$tdir/f0
2261
2262         rm -f $DIR/$tdir/f1
2263         # open f1 with O_LOV_DELAY_CREATE
2264         # unlink f1
2265         # call setstripe ioctl on open file descriptor for f1
2266         # close
2267         multiop $DIR/$tdir/f1 oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:uB1c
2268
2269         # Allow multiop to fail in imitation of NFS's busted semantics.
2270         true
2271 }
2272 run_test 27B "call setstripe on open unlinked file/rename victim"
2273
2274 # 27C family tests full striping and overstriping
2275 test_27Ca() { #LU-2871
2276         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
2277
2278         declare -a ost_idx
2279         local index
2280         local found
2281         local i
2282         local j
2283
2284         test_mkdir $DIR/$tdir
2285         cd $DIR/$tdir
2286         for i in $(seq 0 $((OSTCOUNT - 1))); do
2287                 # set stripe across all OSTs starting from OST$i
2288                 $LFS setstripe -i $i -c -1 $tfile$i
2289                 # get striping information
2290                 ost_idx=($($LFS getstripe $tfile$i |
2291                          tail -n $((OSTCOUNT + 1)) | awk '{print $1}'))
2292                 echo ${ost_idx[@]}
2293
2294                 # check the layout
2295                 [ ${#ost_idx[@]} -eq $OSTCOUNT ] ||
2296                         error "${#ost_idx[@]} != $OSTCOUNT"
2297
2298                 for index in $(seq 0 $((OSTCOUNT - 1))); do
2299                         found=0
2300                         for j in $(echo ${ost_idx[@]}); do
2301                                 if [ $index -eq $j ]; then
2302                                         found=1
2303                                         break
2304                                 fi
2305                         done
2306                         [ $found = 1 ] ||
2307                                 error "Can not find $index in ${ost_idx[@]}"
2308                 done
2309         done
2310 }
2311 run_test 27Ca "check full striping across all OSTs"
2312
2313 test_27Cb() {
2314         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2315                 skip "server does not support overstriping"
2316         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2317                 skip_env "too many osts, skipping"
2318
2319         test_mkdir -p $DIR/$tdir
2320         local setcount=$(($OSTCOUNT * 2))
2321         [ $setcount -ge 160 ] || large_xattr_enabled ||
2322                 skip_env "ea_inode feature disabled"
2323
2324         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2325                 error "setstripe failed"
2326
2327         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2328         [ $count -eq $setcount ] ||
2329                 error "stripe count $count, should be $setcount"
2330
2331         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2332                 error "overstriped should be set in pattern"
2333
2334         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2335                 error "dd failed"
2336 }
2337 run_test 27Cb "more stripes than OSTs with -C"
2338
2339 test_27Cc() {
2340         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2341                 skip "server does not support overstriping"
2342         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2343
2344         test_mkdir -p $DIR/$tdir
2345         local setcount=$(($OSTCOUNT - 1))
2346
2347         [ $setcount -ge 160 ] || large_xattr_enabled ||
2348                 skip_env "ea_inode feature disabled"
2349
2350         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2351                 error "setstripe failed"
2352
2353         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2354         [ $count -eq $setcount ] ||
2355                 error "stripe count $count, should be $setcount"
2356
2357         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" &&
2358                 error "overstriped should not be set in pattern"
2359
2360         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2361                 error "dd failed"
2362 }
2363 run_test 27Cc "fewer stripes than OSTs does not set overstriping"
2364
2365 test_27Cd() {
2366         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2367                 skip "server does not support overstriping"
2368         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2369         large_xattr_enabled || skip_env "ea_inode feature disabled"
2370
2371         test_mkdir -p $DIR/$tdir
2372         local setcount=$LOV_MAX_STRIPE_COUNT
2373
2374         $LFS setstripe -C $setcount $DIR/$tdir/$tfile ||
2375                 error "setstripe failed"
2376
2377         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2378         [ $count -eq $setcount ] ||
2379                 error "stripe count $count, should be $setcount"
2380
2381         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2382                 error "overstriped should be set in pattern"
2383
2384         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2385                 error "dd failed"
2386
2387         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2388 }
2389 run_test 27Cd "test maximum stripe count"
2390
2391 test_27Ce() {
2392         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2393                 skip "server does not support overstriping"
2394         test_mkdir -p $DIR/$tdir
2395
2396         pool_add $TESTNAME || error "Pool creation failed"
2397         pool_add_targets $TESTNAME 0 || error "pool_add_targets failed"
2398
2399         local setcount=8
2400
2401         $LFS setstripe  -C $setcount -p "$TESTNAME" $DIR/$tdir/$tfile ||
2402                 error "setstripe failed"
2403
2404         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2405         [ $count -eq $setcount ] ||
2406                 error "stripe count $count, should be $setcount"
2407
2408         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2409                 error "overstriped should be set in pattern"
2410
2411         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2412                 error "dd failed"
2413
2414         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2415 }
2416 run_test 27Ce "test pool with overstriping"
2417
2418 test_27Cf() {
2419         [[ $($LCTL get_param mdc.*.import) =~ connect_flags.*overstriping ]] ||
2420                 skip "server does not support overstriping"
2421         [[ $OSTCOUNT -ge $(($LOV_MAX_STRIPE_COUNT / 2)) ]] &&
2422                 skip_env "too many osts, skipping"
2423
2424         test_mkdir -p $DIR/$tdir
2425
2426         local setcount=$(($OSTCOUNT * 2))
2427         [ $setcount -ge 160 ] || large_xattr_enabled ||
2428                 skip_env "ea_inode feature disabled"
2429
2430         $LFS setstripe  -C $setcount $DIR/$tdir/ ||
2431                 error "setstripe failed"
2432
2433         echo 1 > $DIR/$tdir/$tfile
2434
2435         local count=$($LFS getstripe -c $DIR/$tdir/$tfile)
2436         [ $count -eq $setcount ] ||
2437                 error "stripe count $count, should be $setcount"
2438
2439         $LFS getstripe $DIR/$tdir/$tfile 2>&1 | grep "overstriped" ||
2440                 error "overstriped should be set in pattern"
2441
2442         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=4 conv=notrunc ||
2443                 error "dd failed"
2444
2445         rm -f $DIR/$tdir/$tfile || error "Delete $tfile failed"
2446 }
2447 run_test 27Cf "test default inheritance with overstriping"
2448
2449 test_27D() {
2450         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
2451         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
2452         remote_mds_nodsh && skip "remote MDS with nodsh"
2453
2454         local POOL=${POOL:-testpool}
2455         local first_ost=0
2456         local last_ost=$(($OSTCOUNT - 1))
2457         local ost_step=1
2458         local ost_list=$(seq $first_ost $ost_step $last_ost)
2459         local ost_range="$first_ost $last_ost $ost_step"
2460
2461         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 test_27M() {
2832         [[ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.12.57) ]] &&
2833                 skip "Need MDS version >= than 2.12.57"
2834         remote_mds_nodsh && skip "remote MDS with nodsh"
2835         [[ $OSTCOUNT -lt 2 ]] && skip_env "need > 1 OST"
2836
2837         test_mkdir $DIR/$tdir
2838
2839         # Set default striping on directory
2840         $LFS setstripe -C 4 $DIR/$tdir
2841
2842         echo 1 > $DIR/$tdir/${tfile}.1
2843         local count=$($LFS getstripe -c $DIR/$tdir/${tfile}.1)
2844         local setcount=4
2845         [ $count -eq $setcount ] ||
2846                 error "(1) stripe count $count, should be $setcount"
2847
2848         # Capture existing append_stripe_count setting for restore
2849         local orig_count=$(do_facet mds1 $LCTL get_param -n mdd.$FSNAME-MDT0000.append_stripe_count)
2850         local mdts=$(comma_list $(mdts_nodes))
2851         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=$orig_count" EXIT
2852
2853         local appendcount=$orig_count
2854         echo 1 >> $DIR/$tdir/${tfile}.2_append
2855         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.2_append)
2856         [ $count -eq $appendcount ] ||
2857                 error "(2)stripe count $count, should be $appendcount for append"
2858
2859         # Disable O_APPEND striping, verify it works
2860         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2861
2862         # Should now get the default striping, which is 4
2863         setcount=4
2864         echo 1 >> $DIR/$tdir/${tfile}.3_append
2865         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.3_append)
2866         [ $count -eq $setcount ] ||
2867                 error "(3) stripe count $count, should be $setcount"
2868
2869         # Try changing the stripe count for append files
2870         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=2
2871
2872         # Append striping is now 2 (directory default is still 4)
2873         appendcount=2
2874         echo 1 >> $DIR/$tdir/${tfile}.4_append
2875         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.4_append)
2876         [ $count -eq $appendcount ] ||
2877                 error "(4) stripe count $count, should be $appendcount for append"
2878
2879         # Test append stripe count of -1
2880         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=-1
2881         appendcount=$OSTCOUNT
2882         echo 1 >> $DIR/$tdir/${tfile}.5
2883         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.5)
2884         [ $count -eq $appendcount ] ||
2885                 error "(5) stripe count $count, should be $appendcount for append"
2886
2887         # Set append striping back to default of 1
2888         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=1
2889
2890         # Try a new default striping, PFL + DOM
2891         $LFS setstripe -L mdt -E 1M -E -1 -c 2 $DIR/$tdir
2892
2893         # Create normal DOM file, DOM returns stripe count == 0
2894         setcount=0
2895         touch $DIR/$tdir/${tfile}.6
2896         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.6)
2897         [ $count -eq $setcount ] ||
2898                 error "(6) stripe count $count, should be $setcount"
2899
2900         # Show
2901         appendcount=1
2902         echo 1 >> $DIR/$tdir/${tfile}.7_append
2903         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.7_append)
2904         [ $count -eq $appendcount ] ||
2905                 error "(7) stripe count $count, should be $appendcount for append"
2906
2907         # Clean up DOM layout
2908         $LFS setstripe -d $DIR/$tdir
2909
2910         # Now test that append striping works when layout is from root
2911         $LFS setstripe -c 2 $MOUNT
2912         # Make a special directory for this
2913         mkdir $DIR/${tdir}/${tdir}.2
2914         stack_trap "$LFS setstripe -d $MOUNT" EXIT
2915
2916         # Verify for normal file
2917         setcount=2
2918         echo 1 > $DIR/${tdir}/${tdir}.2/${tfile}.8
2919         count=$($LFS getstripe -c $DIR/$tdir/${tdir}.2/${tfile}.8)
2920         [ $count -eq $setcount ] ||
2921                 error "(8) stripe count $count, should be $setcount"
2922
2923         appendcount=1
2924         echo 1 >> $DIR/${tdir}/${tdir}.2/${tfile}.9_append
2925         count=$($LFS getstripe -c $DIR/${tdir}/${tdir}.2/${tfile}.9_append)
2926         [ $count -eq $appendcount ] ||
2927                 error "(9) stripe count $count, should be $appendcount for append"
2928
2929         # Now test O_APPEND striping with pools
2930         do_nodes $mdts $LCTL set_param mdd.*.append_pool="$TESTNAME"
2931         stack_trap "do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'" EXIT
2932
2933         # Create the pool
2934         pool_add $TESTNAME || error "pool creation failed"
2935         pool_add_targets $TESTNAME 0 1 || error "Pool add targets failed"
2936
2937         echo 1 >> $DIR/$tdir/${tfile}.10_append
2938
2939         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.10_append)
2940         [ "$pool" = "$TESTNAME" ] || error "(10) incorrect pool: $pool"
2941
2942         # Check that count is still correct
2943         appendcount=1
2944         echo 1 >> $DIR/$tdir/${tfile}.11_append
2945         count=$($LFS getstripe -c $DIR/$tdir/${tfile}.11_append)
2946         [ $count -eq $appendcount ] ||
2947                 error "(11) stripe count $count, should be $appendcount for append"
2948
2949         # Disable O_APPEND stripe count, verify pool works separately
2950         do_nodes $mdts $LCTL set_param mdd.*.append_stripe_count=0
2951
2952         echo 1 >> $DIR/$tdir/${tfile}.12_append
2953
2954         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.12_append)
2955         [ "$pool" = "$TESTNAME" ] || error "(12) incorrect pool: $pool"
2956
2957         # Remove pool setting, verify it's not applied
2958         do_nodes $mdts $LCTL set_param mdd.*.append_pool='none'
2959
2960         echo 1 >> $DIR/$tdir/${tfile}.13_append
2961
2962         pool=$($LFS getstripe -p $DIR/$tdir/${tfile}.13_append)
2963         [ "$pool" = "" ] || error "(13) pool found: $pool"
2964 }
2965 run_test 27M "test O_APPEND striping"
2966
2967 # createtest also checks that device nodes are created and
2968 # then visible correctly (#2091)
2969 test_28() { # bug 2091
2970         test_mkdir $DIR/d28
2971         $CREATETEST $DIR/d28/ct || error "createtest failed"
2972 }
2973 run_test 28 "create/mknod/mkdir with bad file types ============"
2974
2975 test_29() {
2976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
2977
2978         sync; sleep 1; sync # flush out any dirty pages from previous tests
2979         cancel_lru_locks
2980         test_mkdir $DIR/d29
2981         touch $DIR/d29/foo
2982         log 'first d29'
2983         ls -l $DIR/d29
2984
2985         declare -i LOCKCOUNTORIG=0
2986         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
2987                 let LOCKCOUNTORIG=$LOCKCOUNTORIG+$lock_count
2988         done
2989         [ $LOCKCOUNTORIG -eq 0 ] && error "No mdc lock count" && return 1
2990
2991         declare -i LOCKUNUSEDCOUNTORIG=0
2992         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
2993                 let LOCKUNUSEDCOUNTORIG=$LOCKUNUSEDCOUNTORIG+$unused_count
2994         done
2995
2996         log 'second d29'
2997         ls -l $DIR/d29
2998         log 'done'
2999
3000         declare -i LOCKCOUNTCURRENT=0
3001         for lock_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_count); do
3002                 let LOCKCOUNTCURRENT=$LOCKCOUNTCURRENT+$lock_count
3003         done
3004
3005         declare -i LOCKUNUSEDCOUNTCURRENT=0
3006         for unused_count in $(lctl get_param -n ldlm.namespaces.*mdc*.lock_unused_count); do
3007                 let LOCKUNUSEDCOUNTCURRENT=$LOCKUNUSEDCOUNTCURRENT+$unused_count
3008         done
3009
3010         if [[ $LOCKCOUNTCURRENT -gt $LOCKCOUNTORIG ]]; then
3011                 $LCTL set_param -n ldlm.dump_namespaces ""
3012                 error "CURRENT: $LOCKCOUNTCURRENT > $LOCKCOUNTORIG"
3013                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3014                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3015                 return 2
3016         fi
3017         if [[ $LOCKUNUSEDCOUNTCURRENT -gt $LOCKUNUSEDCOUNTORIG ]]; then
3018                 error "UNUSED: $LOCKUNUSEDCOUNTCURRENT > $LOCKUNUSEDCOUNTORIG"
3019                 $LCTL dk | sort -k4 -t: > $TMP/test_29.dk
3020                 log "dumped log to $TMP/test_29.dk (bug 5793)"
3021                 return 3
3022         fi
3023 }
3024 run_test 29 "IT_GETATTR regression  ============================"
3025
3026 test_30a() { # was test_30
3027         cp $(which ls) $DIR || cp /bin/ls $DIR
3028         $DIR/ls / || error "Can't execute binary from lustre"
3029         rm $DIR/ls
3030 }
3031 run_test 30a "execute binary from Lustre (execve) =============="
3032
3033 test_30b() {
3034         cp `which ls` $DIR || cp /bin/ls $DIR
3035         chmod go+rx $DIR/ls
3036         $RUNAS $DIR/ls / || error "Can't execute binary from lustre as non-root"
3037         rm $DIR/ls
3038 }
3039 run_test 30b "execute binary from Lustre as non-root ==========="
3040
3041 test_30c() { # b=22376
3042         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3043
3044         cp `which ls` $DIR || cp /bin/ls $DIR
3045         chmod a-rw $DIR/ls
3046         cancel_lru_locks mdc
3047         cancel_lru_locks osc
3048         $RUNAS $DIR/ls / || error "Can't execute binary from lustre"
3049         rm -f $DIR/ls
3050 }
3051 run_test 30c "execute binary from Lustre without read perms ===="
3052
3053 test_31a() {
3054         $OPENUNLINK $DIR/f31 $DIR/f31 || error "openunlink failed"
3055         $CHECKSTAT -a $DIR/f31 || error "$DIR/f31 exists"
3056 }
3057 run_test 31a "open-unlink file =================================="
3058
3059 test_31b() {
3060         touch $DIR/f31 || error "touch $DIR/f31 failed"
3061         ln $DIR/f31 $DIR/f31b || error "ln failed"
3062         $MULTIOP $DIR/f31b Ouc || error "multiop failed"
3063         $CHECKSTAT -t file $DIR/f31 || error "$DIR/f31 not file type"
3064 }
3065 run_test 31b "unlink file with multiple links while open ======="
3066
3067 test_31c() {
3068         touch $DIR/f31 || error "touch $DIR/f31 failed"
3069         ln $DIR/f31 $DIR/f31c || error "ln failed"
3070         multiop_bg_pause $DIR/f31 O_uc ||
3071                 error "multiop_bg_pause for $DIR/f31 failed"
3072         MULTIPID=$!
3073         $MULTIOP $DIR/f31c Ouc
3074         kill -USR1 $MULTIPID
3075         wait $MULTIPID
3076 }
3077 run_test 31c "open-unlink file with multiple links ============="
3078
3079 test_31d() {
3080         opendirunlink $DIR/d31d $DIR/d31d || error "opendirunlink failed"
3081         $CHECKSTAT -a $DIR/d31d || error "$DIR/d31d exists"
3082 }
3083 run_test 31d "remove of open directory ========================="
3084
3085 test_31e() { # bug 2904
3086         openfilleddirunlink $DIR/d31e || error "openfilleddirunlink failed"
3087 }
3088 run_test 31e "remove of open non-empty directory ==============="
3089
3090 test_31f() { # bug 4554
3091         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3092
3093         set -vx
3094         test_mkdir $DIR/d31f
3095         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3096         cp /etc/hosts $DIR/d31f
3097         ls -l $DIR/d31f
3098         $LFS getstripe $DIR/d31f/hosts
3099         multiop_bg_pause $DIR/d31f D_c || return 1
3100         MULTIPID=$!
3101
3102         rm -rv $DIR/d31f || error "first of $DIR/d31f"
3103         test_mkdir $DIR/d31f
3104         $LFS setstripe -S 1048576 -c 1 $DIR/d31f
3105         cp /etc/hosts $DIR/d31f
3106         ls -l $DIR/d31f
3107         $LFS getstripe $DIR/d31f/hosts
3108         multiop_bg_pause $DIR/d31f D_c || return 1
3109         MULTIPID2=$!
3110
3111         kill -USR1 $MULTIPID || error "first opendir $MULTIPID not running"
3112         wait $MULTIPID || error "first opendir $MULTIPID failed"
3113
3114         sleep 6
3115
3116         kill -USR1 $MULTIPID2 || error "second opendir $MULTIPID not running"
3117         wait $MULTIPID2 || error "second opendir $MULTIPID2 failed"
3118         set +vx
3119 }
3120 run_test 31f "remove of open directory with open-unlink file ==="
3121
3122 test_31g() {
3123         echo "-- cross directory link --"
3124         test_mkdir -c1 $DIR/${tdir}ga
3125         test_mkdir -c1 $DIR/${tdir}gb
3126         touch $DIR/${tdir}ga/f
3127         ln $DIR/${tdir}ga/f $DIR/${tdir}gb/g
3128         $CHECKSTAT -t file $DIR/${tdir}ga/f || error "source"
3129         [ `stat -c%h $DIR/${tdir}ga/f` == '2' ] || error "source nlink"
3130         $CHECKSTAT -t file $DIR/${tdir}gb/g || error "target"
3131         [ `stat -c%h $DIR/${tdir}gb/g` == '2' ] || error "target nlink"
3132 }
3133 run_test 31g "cross directory link==============="
3134
3135 test_31h() {
3136         echo "-- cross directory link --"
3137         test_mkdir -c1 $DIR/${tdir}
3138         test_mkdir -c1 $DIR/${tdir}/dir
3139         touch $DIR/${tdir}/f
3140         ln $DIR/${tdir}/f $DIR/${tdir}/dir/g
3141         $CHECKSTAT -t file $DIR/${tdir}/f || error "source"
3142         [ `stat -c%h $DIR/${tdir}/f` == '2' ] || error "source nlink"
3143         $CHECKSTAT -t file $DIR/${tdir}/dir/g || error "target"
3144         [ `stat -c%h $DIR/${tdir}/dir/g` == '2' ] || error "target nlink"
3145 }
3146 run_test 31h "cross directory link under child==============="
3147
3148 test_31i() {
3149         echo "-- cross directory link --"
3150         test_mkdir -c1 $DIR/$tdir
3151         test_mkdir -c1 $DIR/$tdir/dir
3152         touch $DIR/$tdir/dir/f
3153         ln $DIR/$tdir/dir/f $DIR/$tdir/g
3154         $CHECKSTAT -t file $DIR/$tdir/dir/f || error "source"
3155         [ `stat -c%h $DIR/$tdir/dir/f` == '2' ] || error "source nlink"
3156         $CHECKSTAT -t file $DIR/$tdir/g || error "target"
3157         [ `stat -c%h $DIR/$tdir/g` == '2' ] || error "target nlink"
3158 }
3159 run_test 31i "cross directory link under parent==============="
3160
3161 test_31j() {
3162         test_mkdir -c1 -p $DIR/$tdir
3163         test_mkdir -c1 -p $DIR/$tdir/dir1
3164         ln $DIR/$tdir/dir1 $DIR/$tdir/dir2 && error "ln for dir"
3165         link $DIR/$tdir/dir1 $DIR/$tdir/dir3 && error "link for dir"
3166         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir4 && error "mlink for dir"
3167         mlink $DIR/$tdir/dir1 $DIR/$tdir/dir1 && error "mlink to the same dir"
3168         return 0
3169 }
3170 run_test 31j "link for directory==============="
3171
3172 test_31k() {
3173         test_mkdir -c1 -p $DIR/$tdir
3174         touch $DIR/$tdir/s
3175         touch $DIR/$tdir/exist
3176         mlink $DIR/$tdir/s $DIR/$tdir/t || error "mlink"
3177         mlink $DIR/$tdir/s $DIR/$tdir/exist && error "mlink to exist file"
3178         mlink $DIR/$tdir/s $DIR/$tdir/s && error "mlink to the same file"
3179         mlink $DIR/$tdir/s $DIR/$tdir && error "mlink to parent dir"
3180         mlink $DIR/$tdir $DIR/$tdir/s && error "mlink parent dir to target"
3181         mlink $DIR/$tdir/not-exist $DIR/$tdir/foo && error "mlink non-existing to new"
3182         mlink $DIR/$tdir/not-exist $DIR/$tdir/s && error "mlink non-existing to exist"
3183         return 0
3184 }
3185 run_test 31k "link to file: the same, non-existing, dir==============="
3186
3187 test_31m() {
3188         mkdir $DIR/d31m
3189         touch $DIR/d31m/s
3190         mkdir $DIR/d31m2
3191         touch $DIR/d31m2/exist
3192         mlink $DIR/d31m/s $DIR/d31m2/t || error "mlink"
3193         mlink $DIR/d31m/s $DIR/d31m2/exist && error "mlink to exist file"
3194         mlink $DIR/d31m/s $DIR/d31m2 && error "mlink to parent dir"
3195         mlink $DIR/d31m2 $DIR/d31m/s && error "mlink parent dir to target"
3196         mlink $DIR/d31m/not-exist $DIR/d31m2/foo && error "mlink non-existing to new"
3197         mlink $DIR/d31m/not-exist $DIR/d31m2/s && error "mlink non-existing to exist"
3198         return 0
3199 }
3200 run_test 31m "link to file: the same, non-existing, dir==============="
3201
3202 test_31n() {
3203         touch $DIR/$tfile || error "cannot create '$DIR/$tfile'"
3204         nlink=$(stat --format=%h $DIR/$tfile)
3205         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3206         local fd=$(free_fd)
3207         local cmd="exec $fd<$DIR/$tfile"
3208         eval $cmd
3209         cmd="exec $fd<&-"
3210         trap "eval $cmd" EXIT
3211         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3212         [ ${nlink:--1} -eq 1 ] || error "nlink is $nlink, expected 1"
3213         rm $DIR/$tfile || error "cannot remove '$DIR/$tfile'"
3214         nlink=$(stat --dereference --format=%h /proc/self/fd/$fd)
3215         [ ${nlink:--1} -eq 0 ] || error "nlink is $nlink, expected 0"
3216         eval $cmd
3217 }
3218 run_test 31n "check link count of unlinked file"
3219
3220 link_one() {
3221         local tempfile=$(mktemp $1_XXXXXX)
3222         mlink $tempfile $1 2> /dev/null &&
3223                 echo "$BASHPID: link $tempfile to $1 succeeded"
3224         munlink $tempfile
3225 }
3226
3227 test_31o() { # LU-2901
3228         test_mkdir $DIR/$tdir
3229         for LOOP in $(seq 100); do
3230                 rm -f $DIR/$tdir/$tfile*
3231                 for THREAD in $(seq 8); do
3232                         link_one $DIR/$tdir/$tfile.$LOOP &
3233                 done
3234                 wait
3235                 local LINKS=$(ls -1 $DIR/$tdir | grep -c $tfile.$LOOP)
3236                 [[ $LINKS -gt 1 ]] && ls $DIR/$tdir &&
3237                         error "$LINKS duplicate links to $tfile.$LOOP" &&
3238                         break || true
3239         done
3240 }
3241 run_test 31o "duplicate hard links with same filename"
3242
3243 test_31p() {
3244         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3245
3246         test_mkdir $DIR/$tdir
3247         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3248         $LFS setdirstripe -D -c2 -H all_char $DIR/$tdir/striped_dir
3249
3250         opendirunlink $DIR/$tdir/striped_dir/test1 ||
3251                 error "open unlink test1 failed"
3252         opendirunlink $DIR/$tdir/striped_dir/test2 ||
3253                 error "open unlink test2 failed"
3254
3255         $CHECKSTAT -a $DIR/$tdir/striped_dir/test1 ||
3256                 error "test1 still exists"
3257         $CHECKSTAT -a $DIR/$tdir/striped_dir/test2 ||
3258                 error "test2 still exists"
3259 }
3260 run_test 31p "remove of open striped directory"
3261
3262 cleanup_test32_mount() {
3263         local rc=0
3264         trap 0
3265         local loopdev=$(losetup -a | grep $EXT2_DEV | sed -ne 's/:.*$//p')
3266         $UMOUNT $DIR/$tdir/ext2-mountpoint || rc=$?
3267         losetup -d $loopdev || true
3268         rm -rf $DIR/$tdir
3269         return $rc
3270 }
3271
3272 test_32a() {
3273         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3274
3275         echo "== more mountpoints and symlinks ================="
3276         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3277         trap cleanup_test32_mount EXIT
3278         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3279         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3280                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3281         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/.. ||
3282                 error "$DIR/$tdir/ext2-mountpoint/.. not dir type"
3283         cleanup_test32_mount
3284 }
3285 run_test 32a "stat d32a/ext2-mountpoint/.. ====================="
3286
3287 test_32b() {
3288         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3289
3290         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3291         trap cleanup_test32_mount EXIT
3292         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3293         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3294                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3295         ls -al $DIR/$tdir/ext2-mountpoint/.. ||
3296                 error "Can't list $DIR/$tdir/ext2-mountpoint/.."
3297         cleanup_test32_mount
3298 }
3299 run_test 32b "open d32b/ext2-mountpoint/.. ====================="
3300
3301 test_32c() {
3302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3303
3304         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3305         trap cleanup_test32_mount EXIT
3306         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3307         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3308                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3309         test_mkdir -p $DIR/$tdir/d2/test_dir
3310         $CHECKSTAT -t dir $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3311                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_dir not dir type"
3312         cleanup_test32_mount
3313 }
3314 run_test 32c "stat d32c/ext2-mountpoint/../d2/test_dir ========="
3315
3316 test_32d() {
3317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3318
3319         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3320         trap cleanup_test32_mount EXIT
3321         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3322         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3323                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3324         test_mkdir -p $DIR/$tdir/d2/test_dir
3325         ls -al $DIR/$tdir/ext2-mountpoint/../d2/test_dir ||
3326                 error "Can't list $DIR/$tdir/ext2-mountpoint/../d2/test_dir"
3327         cleanup_test32_mount
3328 }
3329 run_test 32d "open d32d/ext2-mountpoint/../d2/test_dir"
3330
3331 test_32e() {
3332         rm -fr $DIR/$tdir
3333         test_mkdir -p $DIR/$tdir/tmp
3334         local tmp_dir=$DIR/$tdir/tmp
3335         ln -s $DIR/$tdir $tmp_dir/symlink11
3336         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3337         $CHECKSTAT -t link $DIR/$tdir/tmp/symlink11 || error "symlink11 bad"
3338         $CHECKSTAT -t link $DIR/$tdir/symlink01 || error "symlink01 bad"
3339 }
3340 run_test 32e "stat d32e/symlink->tmp/symlink->lustre-subdir"
3341
3342 test_32f() {
3343         rm -fr $DIR/$tdir
3344         test_mkdir -p $DIR/$tdir/tmp
3345         local tmp_dir=$DIR/$tdir/tmp
3346         ln -s $DIR/$tdir $tmp_dir/symlink11
3347         ln -s $tmp_dir/symlink11 $tmp_dir/../symlink01
3348         ls $DIR/$tdir/tmp/symlink11  || error "symlink11 bad"
3349         ls $DIR/$tdir/symlink01 || error "symlink01 bad"
3350 }
3351 run_test 32f "open d32f/symlink->tmp/symlink->lustre-subdir"
3352
3353 test_32g() {
3354         local tmp_dir=$DIR/$tdir/tmp
3355         test_mkdir -p $tmp_dir
3356         test_mkdir $DIR/${tdir}2
3357         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3358         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3359         $CHECKSTAT -t link $tmp_dir/symlink12 || error "symlink12 not a link"
3360         $CHECKSTAT -t link $DIR/$tdir/symlink02 || error "symlink02 not a link"
3361         $CHECKSTAT -t dir -f $tmp_dir/symlink12 || error "symlink12 not a dir"
3362         $CHECKSTAT -t dir -f $DIR/$tdir/symlink02 || error "symlink12 not a dir"
3363 }
3364 run_test 32g "stat d32g/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3365
3366 test_32h() {
3367         rm -fr $DIR/$tdir $DIR/${tdir}2
3368         tmp_dir=$DIR/$tdir/tmp
3369         test_mkdir -p $tmp_dir
3370         test_mkdir $DIR/${tdir}2
3371         ln -s $DIR/${tdir}2 $tmp_dir/symlink12
3372         ln -s $tmp_dir/symlink12 $tmp_dir/../symlink02
3373         ls $tmp_dir/symlink12 || error "listing symlink12"
3374         ls $DIR/$tdir/symlink02  || error "listing symlink02"
3375 }
3376 run_test 32h "open d32h/symlink->tmp/symlink->lustre-subdir/${tdir}2"
3377
3378 test_32i() {
3379         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3380
3381         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3382         trap cleanup_test32_mount EXIT
3383         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3384         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3385                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3386         touch $DIR/$tdir/test_file
3387         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../test_file ||
3388                 error "$DIR/$tdir/ext2-mountpoint/../test_file not file type"
3389         cleanup_test32_mount
3390 }
3391 run_test 32i "stat d32i/ext2-mountpoint/../test_file ==========="
3392
3393 test_32j() {
3394         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3395
3396         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3397         trap cleanup_test32_mount EXIT
3398         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3399         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3400                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3401         touch $DIR/$tdir/test_file
3402         cat $DIR/$tdir/ext2-mountpoint/../test_file ||
3403                 error "Can't open $DIR/$tdir/ext2-mountpoint/../test_file"
3404         cleanup_test32_mount
3405 }
3406 run_test 32j "open d32j/ext2-mountpoint/../test_file ==========="
3407
3408 test_32k() {
3409         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3410
3411         rm -fr $DIR/$tdir
3412         trap cleanup_test32_mount EXIT
3413         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3414         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3415                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3416         test_mkdir -p $DIR/$tdir/d2
3417         touch $DIR/$tdir/d2/test_file || error "touch failed"
3418         $CHECKSTAT -t file $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3419                 error "$DIR/$tdir/ext2-mountpoint/../d2/test_file not file type"
3420         cleanup_test32_mount
3421 }
3422 run_test 32k "stat d32k/ext2-mountpoint/../d2/test_file ========"
3423
3424 test_32l() {
3425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3426
3427         rm -fr $DIR/$tdir
3428         trap cleanup_test32_mount EXIT
3429         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3430         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3431                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3432         test_mkdir -p $DIR/$tdir/d2
3433         touch $DIR/$tdir/d2/test_file || error "touch failed"
3434         cat  $DIR/$tdir/ext2-mountpoint/../d2/test_file ||
3435                 error "Can't open $DIR/$tdir/ext2-mountpoint/../d2/test_file"
3436         cleanup_test32_mount
3437 }
3438 run_test 32l "open d32l/ext2-mountpoint/../d2/test_file ========"
3439
3440 test_32m() {
3441         rm -fr $DIR/d32m
3442         test_mkdir -p $DIR/d32m/tmp
3443         TMP_DIR=$DIR/d32m/tmp
3444         ln -s $DIR $TMP_DIR/symlink11
3445         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3446         $CHECKSTAT -t link $DIR/d32m/tmp/symlink11 ||
3447                 error "symlink11 not a link"
3448         $CHECKSTAT -t link $DIR/d32m/symlink01 ||
3449                 error "symlink01 not a link"
3450 }
3451 run_test 32m "stat d32m/symlink->tmp/symlink->lustre-root ======"
3452
3453 test_32n() {
3454         rm -fr $DIR/d32n
3455         test_mkdir -p $DIR/d32n/tmp
3456         TMP_DIR=$DIR/d32n/tmp
3457         ln -s $DIR $TMP_DIR/symlink11
3458         ln -s $TMP_DIR/symlink11 $TMP_DIR/../symlink01
3459         ls -l $DIR/d32n/tmp/symlink11  || error "listing symlink11"
3460         ls -l $DIR/d32n/symlink01 || error "listing symlink01"
3461 }
3462 run_test 32n "open d32n/symlink->tmp/symlink->lustre-root ======"
3463
3464 test_32o() {
3465         touch $DIR/$tfile
3466         test_mkdir -p $DIR/d32o/tmp
3467         TMP_DIR=$DIR/d32o/tmp
3468         ln -s $DIR/$tfile $TMP_DIR/symlink12
3469         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3470         $CHECKSTAT -t link $DIR/d32o/tmp/symlink12 ||
3471                 error "symlink12 not a link"
3472         $CHECKSTAT -t link $DIR/d32o/symlink02 || error "symlink02 not a link"
3473         $CHECKSTAT -t file -f $DIR/d32o/tmp/symlink12 ||
3474                 error "$DIR/d32o/tmp/symlink12 not file type"
3475         $CHECKSTAT -t file -f $DIR/d32o/symlink02 ||
3476                 error "$DIR/d32o/symlink02 not file type"
3477 }
3478 run_test 32o "stat d32o/symlink->tmp/symlink->lustre-root/$tfile"
3479
3480 test_32p() {
3481         log 32p_1
3482         rm -fr $DIR/d32p
3483         log 32p_2
3484         rm -f $DIR/$tfile
3485         log 32p_3
3486         touch $DIR/$tfile
3487         log 32p_4
3488         test_mkdir -p $DIR/d32p/tmp
3489         log 32p_5
3490         TMP_DIR=$DIR/d32p/tmp
3491         log 32p_6
3492         ln -s $DIR/$tfile $TMP_DIR/symlink12
3493         log 32p_7
3494         ln -s $TMP_DIR/symlink12 $TMP_DIR/../symlink02
3495         log 32p_8
3496         cat $DIR/d32p/tmp/symlink12 ||
3497                 error "Can't open $DIR/d32p/tmp/symlink12"
3498         log 32p_9
3499         cat $DIR/d32p/symlink02 || error "Can't open $DIR/d32p/symlink02"
3500         log 32p_10
3501 }
3502 run_test 32p "open d32p/symlink->tmp/symlink->lustre-root/$tfile"
3503
3504 test_32q() {
3505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3506
3507         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3508         trap cleanup_test32_mount EXIT
3509         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3510         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3511         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3512                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3513         ls $DIR/$tdir/ext2-mountpoint | grep "\<under_the_mount\>" && error
3514         cleanup_test32_mount
3515 }
3516 run_test 32q "stat follows mountpoints in Lustre (should return error)"
3517
3518 test_32r() {
3519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3520
3521         [ -e $DIR/$tdir ] && rm -fr $DIR/$tdir
3522         trap cleanup_test32_mount EXIT
3523         test_mkdir -p $DIR/$tdir/ext2-mountpoint
3524         touch $DIR/$tdir/ext2-mountpoint/under_the_mount || error "touch failed"
3525         mount -t ext2 -o loop $EXT2_DEV $DIR/$tdir/ext2-mountpoint ||
3526                 error "mount failed for $EXT2_DEV $DIR/$tdir/ext2-mountpoint"
3527         ls $DIR/$tdir/ext2-mountpoint | grep -q under_the_mount && error || true
3528         cleanup_test32_mount
3529 }
3530 run_test 32r "opendir follows mountpoints in Lustre (should return error)"
3531
3532 test_33aa() {
3533         rm -f $DIR/$tfile
3534         touch $DIR/$tfile
3535         chmod 444 $DIR/$tfile
3536         chown $RUNAS_ID $DIR/$tfile
3537         log 33_1
3538         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3539         log 33_2
3540 }
3541 run_test 33aa "write file with mode 444 (should return error)"
3542
3543 test_33a() {
3544         rm -fr $DIR/$tdir
3545         test_mkdir $DIR/$tdir
3546         chown $RUNAS_ID $DIR/$tdir
3547         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile ||
3548                 error "$RUNAS create $tdir/$tfile failed"
3549         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $DIR/$tdir/$tfile &&
3550                 error "open RDWR" || true
3551 }
3552 run_test 33a "test open file(mode=0444) with O_RDWR (should return error)"
3553
3554 test_33b() {
3555         rm -fr $DIR/$tdir
3556         test_mkdir $DIR/$tdir
3557         chown $RUNAS_ID $DIR/$tdir
3558         $RUNAS $OPENFILE -f 1286739555 $DIR/$tdir/$tfile || true
3559 }
3560 run_test 33b "test open file with malformed flags (No panic)"
3561
3562 test_33c() {
3563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3564         remote_ost_nodsh && skip "remote OST with nodsh"
3565
3566         local ostnum
3567         local ostname
3568         local write_bytes
3569         local all_zeros
3570
3571         all_zeros=:
3572         rm -fr $DIR/$tdir
3573         test_mkdir $DIR/$tdir
3574         # Read: 0, Write: 4, create/destroy: 2/0, stat: 1, punch: 0
3575
3576         sync
3577         for ostnum in $(seq $OSTCOUNT); do
3578                 # test-framework's OST numbering is one-based, while Lustre's
3579                 # is zero-based
3580                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3581                 # Parsing llobdstat's output sucks; we could grep the /proc
3582                 # path, but that's likely to not be as portable as using the
3583                 # llobdstat utility.  So we parse lctl output instead.
3584                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3585                         obdfilter/$ostname/stats |
3586                         awk '/^write_bytes/ {print $7}' )
3587                 echo "baseline_write_bytes@$OSTnum/$ostname=$write_bytes"
3588                 if (( ${write_bytes:-0} > 0 ))
3589                 then
3590                         all_zeros=false
3591                         break;
3592                 fi
3593         done
3594
3595         $all_zeros || return 0
3596
3597         # Write four bytes
3598         echo foo > $DIR/$tdir/bar
3599         # Really write them
3600         sync
3601
3602         # Total up write_bytes after writing.  We'd better find non-zeros.
3603         for ostnum in $(seq $OSTCOUNT); do
3604                 ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3605                 write_bytes=$(do_facet ost$ostnum lctl get_param -n \
3606                         obdfilter/$ostname/stats |
3607                         awk '/^write_bytes/ {print $7}' )
3608                 echo "write_bytes@$OSTnum/$ostname=$write_bytes"
3609                 if (( ${write_bytes:-0} > 0 ))
3610                 then
3611                         all_zeros=false
3612                         break;
3613                 fi
3614         done
3615
3616         if $all_zeros
3617         then
3618                 for ostnum in $(seq $OSTCOUNT); do
3619                         ostname=$(printf "$FSNAME-OST%.4x" $((ostnum - 1)))
3620                         echo "Check that write_bytes is present in obdfilter/*/stats:"
3621                         do_facet ost$ostnum lctl get_param -n \
3622                                 obdfilter/$ostname/stats
3623                 done
3624                 error "OST not keeping write_bytes stats (b22312)"
3625         fi
3626 }
3627 run_test 33c "test llobdstat and write_bytes"
3628
3629 test_33d() {
3630         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
3631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3632
3633         local MDTIDX=1
3634         local remote_dir=$DIR/$tdir/remote_dir
3635
3636         test_mkdir $DIR/$tdir
3637         $LFS mkdir -i $MDTIDX $remote_dir ||
3638                 error "create remote directory failed"
3639
3640         touch $remote_dir/$tfile
3641         chmod 444 $remote_dir/$tfile
3642         chown $RUNAS_ID $remote_dir/$tfile
3643
3644         $RUNAS $OPENFILE -f O_RDWR $DIR/$tfile && error || true
3645
3646         chown $RUNAS_ID $remote_dir
3647         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 ||
3648                                         error "create" || true
3649         $RUNAS $OPENFILE -f O_RDWR:O_CREAT -m 0444 $remote_dir/f33 &&
3650                                     error "open RDWR" || true
3651         $RUNAS $OPENFILE -f 1286739555 $remote_dir/f33 || true
3652 }
3653 run_test 33d "openfile with 444 modes and malformed flags under remote dir"
3654
3655 test_33e() {
3656         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3657
3658         mkdir $DIR/$tdir
3659
3660         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3661         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3662         mkdir $DIR/$tdir/local_dir
3663
3664         local s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3665         local s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3666         local l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3667
3668         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3669                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode"
3670
3671         rmdir $DIR/$tdir/* || error "rmdir failed"
3672
3673         umask 777
3674         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3675         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3676         mkdir $DIR/$tdir/local_dir
3677
3678         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3679         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3680         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3681
3682         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3683                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 777"
3684
3685         rmdir $DIR/$tdir/* || error "rmdir(umask 777) failed"
3686
3687         umask 000
3688         $LFS setdirstripe -i0 -c2 $DIR/$tdir/striped_dir
3689         $LFS setdirstripe -i1 -c2 $DIR/$tdir/striped_dir1
3690         mkdir $DIR/$tdir/local_dir
3691
3692         s0_mode=$(stat -c%f $DIR/$tdir/striped_dir)
3693         s1_mode=$(stat -c%f $DIR/$tdir/striped_dir1)
3694         l_mode=$(stat -c%f $DIR/$tdir/local_dir)
3695
3696         [ "$l_mode" = "$s0_mode" -a "$l_mode" = "$s1_mode" ] ||
3697                 error "mkdir $l_mode striped0 $s0_mode striped1 $s1_mode 0"
3698 }
3699 run_test 33e "mkdir and striped directory should have same mode"
3700
3701 cleanup_33f() {
3702         trap 0
3703         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=0
3704 }
3705
3706 test_33f() {
3707         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3708         remote_mds_nodsh && skip "remote MDS with nodsh"
3709
3710         mkdir $DIR/$tdir
3711         chmod go+rwx $DIR/$tdir
3712         do_facet $SINGLEMDS $LCTL set_param mdt.*.enable_remote_dir_gid=-1
3713         trap cleanup_33f EXIT
3714
3715         $RUNAS lfs mkdir -i 0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
3716                 error "cannot create striped directory"
3717
3718         $RUNAS touch $DIR/$tdir/striped_dir/{0..16} ||
3719                 error "cannot create files in striped directory"
3720
3721         $RUNAS rm $DIR/$tdir/striped_dir/{0..16} ||
3722                 error "cannot remove files in striped directory"
3723
3724         $RUNAS rmdir $DIR/$tdir/striped_dir ||
3725                 error "cannot remove striped directory"
3726
3727         cleanup_33f
3728 }
3729 run_test 33f "nonroot user can create, access, and remove a striped directory"
3730
3731 test_33g() {
3732         mkdir -p $DIR/$tdir/dir2
3733
3734         local err=$($RUNAS mkdir $DIR/$tdir/dir2 2>&1)
3735         echo $err
3736         [[ $err =~ "exists" ]] || error "Not exists error"
3737 }
3738 run_test 33g "nonroot user create already existing root created file"
3739
3740 TEST_34_SIZE=${TEST_34_SIZE:-2000000000000}
3741 test_34a() {
3742         rm -f $DIR/f34
3743         $MCREATE $DIR/f34 || error "mcreate failed"
3744         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3745                 error "getstripe failed"
3746         $TRUNCATE $DIR/f34 $TEST_34_SIZE || error "truncate failed"
3747         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3748                 error "getstripe failed"
3749         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3750                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3751 }
3752 run_test 34a "truncate file that has not been opened ==========="
3753
3754 test_34b() {
3755         [ ! -f $DIR/f34 ] && test_34a
3756         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3757                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3758         $OPENFILE -f O_RDONLY $DIR/f34
3759         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" ||
3760                 error "getstripe failed"
3761         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3762                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3763 }
3764 run_test 34b "O_RDONLY opening file doesn't create objects ====="
3765
3766 test_34c() {
3767         [ ! -f $DIR/f34 ] && test_34a
3768         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3769                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3770         $OPENFILE -f O_RDWR $DIR/f34
3771         $LFS getstripe $DIR/f34 2>&1 | grep -q "no stripe info" &&
3772                 error "$LFS getstripe failed"
3773         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3774                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3775 }
3776 run_test 34c "O_RDWR opening file-with-size works =============="
3777
3778 test_34d() {
3779         [ ! -f $DIR/f34 ] && test_34a
3780         dd if=/dev/zero of=$DIR/f34 conv=notrunc bs=4k count=1 ||
3781                 error "dd failed"
3782         $CHECKSTAT -s $TEST_34_SIZE $DIR/f34 ||
3783                 error "Size of $DIR/f34 not equal to $TEST_34_SIZE bytes"
3784         rm $DIR/f34
3785 }
3786 run_test 34d "write to sparse file ============================="
3787
3788 test_34e() {
3789         rm -f $DIR/f34e
3790         $MCREATE $DIR/f34e || error "mcreate failed"
3791         $TRUNCATE $DIR/f34e 1000 || error "truncate failed"
3792         $CHECKSTAT -s 1000 $DIR/f34e ||
3793                 error "Size of $DIR/f34e not equal to 1000 bytes"
3794         $OPENFILE -f O_RDWR $DIR/f34e
3795         $CHECKSTAT -s 1000 $DIR/f34e ||
3796                 error "Size of $DIR/f34e not equal to 1000 bytes"
3797 }
3798 run_test 34e "create objects, some with size and some without =="
3799
3800 test_34f() { # bug 6242, 6243
3801         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3802
3803         SIZE34F=48000
3804         rm -f $DIR/f34f
3805         $MCREATE $DIR/f34f || error "mcreate failed"
3806         $TRUNCATE $DIR/f34f $SIZE34F || error "truncating $DIR/f3f to $SIZE34F"
3807         dd if=$DIR/f34f of=$TMP/f34f
3808         $CHECKSTAT -s $SIZE34F $TMP/f34f || error "$TMP/f34f not $SIZE34F bytes"
3809         dd if=/dev/zero of=$TMP/f34fzero bs=$SIZE34F count=1
3810         cmp $DIR/f34f $TMP/f34fzero || error "$DIR/f34f not all zero"
3811         cmp $TMP/f34f $TMP/f34fzero || error "$TMP/f34f not all zero"
3812         rm $TMP/f34f $TMP/f34fzero $DIR/f34f
3813 }
3814 run_test 34f "read from a file with no objects until EOF ======="
3815
3816 test_34g() {
3817         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3818
3819         dd if=/dev/zero of=$DIR/$tfile bs=1 count=100 seek=$TEST_34_SIZE ||
3820                 error "dd failed"
3821         $TRUNCATE $DIR/$tfile $((TEST_34_SIZE / 2))|| error "truncate failed"
3822         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3823                 error "Size of $DIR/$tfile not equal to $((TEST_34_SIZE / 2))"
3824         cancel_lru_locks osc
3825         $CHECKSTAT -s $((TEST_34_SIZE / 2)) $DIR/$tfile ||
3826                 error "wrong size after lock cancel"
3827
3828         $TRUNCATE $DIR/$tfile $TEST_34_SIZE || error "truncate failed"
3829         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3830                 error "expanding truncate failed"
3831         cancel_lru_locks osc
3832         $CHECKSTAT -s $TEST_34_SIZE $DIR/$tfile ||
3833                 error "wrong expanded size after lock cancel"
3834 }
3835 run_test 34g "truncate long file ==============================="
3836
3837 test_34h() {
3838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3839
3840         local gid=10
3841         local sz=1000
3842
3843         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10 || error "dd failed"
3844         sync # Flush the cache so that multiop below does not block on cache
3845              # flush when getting the group lock
3846         $MULTIOP $DIR/$tfile OG${gid}T${sz}g${gid}c &
3847         MULTIPID=$!
3848
3849         # Since just timed wait is not good enough, let's do a sync write
3850         # that way we are sure enough time for a roundtrip + processing
3851         # passed + 2 seconds of extra margin.
3852         dd if=/dev/zero of=$DIR/${tfile}-1 bs=$PAGE_SIZE oflag=direct count=1
3853         rm $DIR/${tfile}-1
3854         sleep 2
3855
3856         if [[ `ps h -o comm -p $MULTIPID` == "multiop" ]]; then
3857                 error "Multiop blocked on ftruncate, pid=$MULTIPID"
3858                 kill -9 $MULTIPID
3859         fi
3860         wait $MULTIPID
3861         local nsz=`stat -c %s $DIR/$tfile`
3862         [[ $nsz == $sz ]] || error "New size wrong $nsz != $sz"
3863 }
3864 run_test 34h "ftruncate file under grouplock should not block"
3865
3866 test_35a() {
3867         cp /bin/sh $DIR/f35a
3868         chmod 444 $DIR/f35a
3869         chown $RUNAS_ID $DIR/f35a
3870         $RUNAS $DIR/f35a && error || true
3871         rm $DIR/f35a
3872 }
3873 run_test 35a "exec file with mode 444 (should return and not leak)"
3874
3875 test_36a() {
3876         rm -f $DIR/f36
3877         utime $DIR/f36 || error "utime failed for MDS"
3878 }
3879 run_test 36a "MDS utime check (mknod, utime)"
3880
3881 test_36b() {
3882         echo "" > $DIR/f36
3883         utime $DIR/f36 || error "utime failed for OST"
3884 }
3885 run_test 36b "OST utime check (open, utime)"
3886
3887 test_36c() {
3888         rm -f $DIR/d36/f36
3889         test_mkdir $DIR/d36
3890         chown $RUNAS_ID $DIR/d36
3891         $RUNAS utime $DIR/d36/f36 || error "utime failed for MDS as non-root"
3892 }
3893 run_test 36c "non-root MDS utime check (mknod, utime)"
3894
3895 test_36d() {
3896         [ ! -d $DIR/d36 ] && test_36c
3897         echo "" > $DIR/d36/f36
3898         $RUNAS utime $DIR/d36/f36 || error "utime failed for OST as non-root"
3899 }
3900 run_test 36d "non-root OST utime check (open, utime)"
3901
3902 test_36e() {
3903         [ $RUNAS_ID -eq $UID ] && skip_env "RUNAS_ID = UID = $UID -- skipping"
3904
3905         test_mkdir $DIR/$tdir
3906         touch $DIR/$tdir/$tfile
3907         $RUNAS utime $DIR/$tdir/$tfile &&
3908                 error "utime worked, expected failure" || true
3909 }
3910 run_test 36e "utime on non-owned file (should return error)"
3911
3912 subr_36fh() {
3913         local fl="$1"
3914         local LANG_SAVE=$LANG
3915         local LC_LANG_SAVE=$LC_LANG
3916         export LANG=C LC_LANG=C # for date language
3917
3918         DATESTR="Dec 20  2000"
3919         test_mkdir $DIR/$tdir
3920         lctl set_param fail_loc=$fl
3921         date; date +%s
3922         cp /etc/hosts $DIR/$tdir/$tfile
3923         sync & # write RPC generated with "current" inode timestamp, but delayed
3924         sleep 1
3925         touch --date="$DATESTR" $DIR/$tdir/$tfile # setattr timestamp in past
3926         LS_BEFORE="`ls -l $DIR/$tdir/$tfile`" # old timestamp from client cache
3927         cancel_lru_locks $OSC
3928         LS_AFTER="`ls -l $DIR/$tdir/$tfile`"  # timestamp from OST object
3929         date; date +%s
3930         [ "$LS_BEFORE" != "$LS_AFTER" ] && \
3931                 echo "BEFORE: $LS_BEFORE" && \
3932                 echo "AFTER : $LS_AFTER" && \
3933                 echo "WANT  : $DATESTR" && \
3934                 error "$DIR/$tdir/$tfile timestamps changed" || true
3935
3936         export LANG=$LANG_SAVE LC_LANG=$LC_LANG_SAVE
3937 }
3938
3939 test_36f() {
3940         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3941
3942         #define OBD_FAIL_OST_BRW_PAUSE_BULK 0x214
3943         subr_36fh "0x80000214"
3944 }
3945 run_test 36f "utime on file racing with OST BRW write =========="
3946
3947 test_36g() {
3948         remote_ost_nodsh && skip "remote OST with nodsh"
3949         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3950         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
3951                 skip "Need MDS version at least 2.12.51"
3952
3953         local fmd_max_age
3954         local fmd
3955         local facet="ost1"
3956         local tgt="obdfilter"
3957
3958         [[ $OSC == "mdc" ]] && tgt="mdt" && facet="mds1"
3959
3960         test_mkdir $DIR/$tdir
3961         fmd_max_age=$(do_facet $facet \
3962                 "lctl get_param -n $tgt.*.tgt_fmd_seconds 2> /dev/null | \
3963                 head -n 1")
3964
3965         echo "FMD max age: ${fmd_max_age}s"
3966         touch $DIR/$tdir/$tfile
3967         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3968                 gawk '{cnt=cnt+$1}  END{print cnt}')
3969         echo "FMD before: $fmd"
3970         [[ $fmd == 0 ]] &&
3971                 error "FMD wasn't create by touch"
3972         sleep $((fmd_max_age + 12))
3973         fmd=$(do_facet $facet "lctl get_param -n $tgt.*.exports.*.fmd_count" |
3974                 gawk '{cnt=cnt+$1}  END{print cnt}')
3975         echo "FMD after: $fmd"
3976         [[ $fmd == 0 ]] ||
3977                 error "FMD wasn't expired by ping"
3978 }
3979 run_test 36g "FMD cache expiry ====================="
3980
3981 test_36h() {
3982         [ $PARALLEL == "yes" ] && skip "skip parallel run"
3983
3984         #define OBD_FAIL_OST_BRW_PAUSE_BULK2 0x227
3985         subr_36fh "0x80000227"
3986 }
3987 run_test 36h "utime on file racing with OST BRW write =========="
3988
3989 test_36i() {
3990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
3991
3992         test_mkdir $DIR/$tdir
3993         $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir
3994
3995         local mtime=$(stat -c%Y $DIR/$tdir/striped_dir)
3996         local new_mtime=$((mtime + 200))
3997
3998         #change Modify time of striped dir
3999         touch -m -d @$new_mtime $DIR/$tdir/striped_dir ||
4000                         error "change mtime failed"
4001
4002         local got=$(stat -c%Y $DIR/$tdir/striped_dir)
4003
4004         [ "$new_mtime" = "$got" ] || error "expect $new_mtime got $got"
4005 }
4006 run_test 36i "change mtime on striped directory"
4007
4008 # test_37 - duplicate with tests 32q 32r
4009
4010 test_38() {
4011         local file=$DIR/$tfile
4012         touch $file
4013         openfile -f O_DIRECTORY $file
4014         local RC=$?
4015         local ENOTDIR=20
4016         [ $RC -eq 0 ] && error "opened file $file with O_DIRECTORY" || true
4017         [ $RC -eq $ENOTDIR ] || error "error $RC should be ENOTDIR ($ENOTDIR)"
4018 }
4019 run_test 38 "open a regular file with O_DIRECTORY should return -ENOTDIR ==="
4020
4021 test_39a() { # was test_39
4022         touch $DIR/$tfile
4023         touch $DIR/${tfile}2
4024 #       ls -l  $DIR/$tfile $DIR/${tfile}2
4025 #       ls -lu  $DIR/$tfile $DIR/${tfile}2
4026 #       ls -lc  $DIR/$tfile $DIR/${tfile}2
4027         sleep 2
4028         $OPENFILE -f O_CREAT:O_TRUNC:O_WRONLY $DIR/${tfile}2
4029         if [ ! $DIR/${tfile}2 -nt $DIR/$tfile ]; then
4030                 echo "mtime"
4031                 ls -l --full-time $DIR/$tfile $DIR/${tfile}2
4032                 echo "atime"
4033                 ls -lu --full-time $DIR/$tfile $DIR/${tfile}2
4034                 echo "ctime"
4035                 ls -lc --full-time $DIR/$tfile $DIR/${tfile}2
4036                 error "O_TRUNC didn't change timestamps"
4037         fi
4038 }
4039 run_test 39a "mtime changed on create"
4040
4041 test_39b() {
4042         test_mkdir -c1 $DIR/$tdir
4043         cp -p /etc/passwd $DIR/$tdir/fopen
4044         cp -p /etc/passwd $DIR/$tdir/flink
4045         cp -p /etc/passwd $DIR/$tdir/funlink
4046         cp -p /etc/passwd $DIR/$tdir/frename
4047         ln $DIR/$tdir/funlink $DIR/$tdir/funlink2
4048
4049         sleep 1
4050         echo "aaaaaa" >> $DIR/$tdir/fopen
4051         echo "aaaaaa" >> $DIR/$tdir/flink
4052         echo "aaaaaa" >> $DIR/$tdir/funlink
4053         echo "aaaaaa" >> $DIR/$tdir/frename
4054
4055         local open_new=`stat -c %Y $DIR/$tdir/fopen`
4056         local link_new=`stat -c %Y $DIR/$tdir/flink`
4057         local unlink_new=`stat -c %Y $DIR/$tdir/funlink`
4058         local rename_new=`stat -c %Y $DIR/$tdir/frename`
4059
4060         cat $DIR/$tdir/fopen > /dev/null
4061         ln $DIR/$tdir/flink $DIR/$tdir/flink2
4062         rm -f $DIR/$tdir/funlink2
4063         mv -f $DIR/$tdir/frename $DIR/$tdir/frename2
4064
4065         for (( i=0; i < 2; i++ )) ; do
4066                 local open_new2=`stat -c %Y $DIR/$tdir/fopen`
4067                 local link_new2=`stat -c %Y $DIR/$tdir/flink`
4068                 local unlink_new2=`stat -c %Y $DIR/$tdir/funlink`
4069                 local rename_new2=`stat -c %Y $DIR/$tdir/frename2`
4070
4071                 [ $open_new2 -eq $open_new ] || error "open file reverses mtime"
4072                 [ $link_new2 -eq $link_new ] || error "link file reverses mtime"
4073                 [ $unlink_new2 -eq $unlink_new ] || error "unlink file reverses mtime"
4074                 [ $rename_new2 -eq $rename_new ] || error "rename file reverses mtime"
4075
4076                 cancel_lru_locks $OSC
4077                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4078         done
4079 }
4080 run_test 39b "mtime change on open, link, unlink, rename  ======"
4081
4082 # this should be set to past
4083 TEST_39_MTIME=`date -d "1 year ago" +%s`
4084
4085 # bug 11063
4086 test_39c() {
4087         touch $DIR1/$tfile
4088         sleep 2
4089         local mtime0=`stat -c %Y $DIR1/$tfile`
4090
4091         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4092         local mtime1=`stat -c %Y $DIR1/$tfile`
4093         [ "$mtime1" = $TEST_39_MTIME ] || \
4094                 error "mtime is not set to past: $mtime1, should be $TEST_39_MTIME"
4095
4096         local d1=`date +%s`
4097         echo hello >> $DIR1/$tfile
4098         local d2=`date +%s`
4099         local mtime2=`stat -c %Y $DIR1/$tfile`
4100         [ "$mtime2" -ge "$d1" ] && [ "$mtime2" -le "$d2" ] || \
4101                 error "mtime is not updated on write: $d1 <= $mtime2 <= $d2"
4102
4103         mv $DIR1/$tfile $DIR1/$tfile-1
4104
4105         for (( i=0; i < 2; i++ )) ; do
4106                 local mtime3=`stat -c %Y $DIR1/$tfile-1`
4107                 [ "$mtime2" = "$mtime3" ] || \
4108                         error "mtime ($mtime2) changed (to $mtime3) on rename"
4109
4110                 cancel_lru_locks $OSC
4111                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4112         done
4113 }
4114 run_test 39c "mtime change on rename ==========================="
4115
4116 # bug 21114
4117 test_39d() {
4118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4119
4120         touch $DIR1/$tfile
4121         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4122
4123         for (( i=0; i < 2; i++ )) ; do
4124                 local mtime=`stat -c %Y $DIR1/$tfile`
4125                 [ $mtime = $TEST_39_MTIME ] || \
4126                         error "mtime($mtime) is not set to $TEST_39_MTIME"
4127
4128                 cancel_lru_locks $OSC
4129                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4130         done
4131 }
4132 run_test 39d "create, utime, stat =============================="
4133
4134 # bug 21114
4135 test_39e() {
4136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4137
4138         touch $DIR1/$tfile
4139         local mtime1=`stat -c %Y $DIR1/$tfile`
4140
4141         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4142
4143         for (( i=0; i < 2; i++ )) ; do
4144                 local mtime2=`stat -c %Y $DIR1/$tfile`
4145                 [ $mtime2 = $TEST_39_MTIME ] || \
4146                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4147
4148                 cancel_lru_locks $OSC
4149                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4150         done
4151 }
4152 run_test 39e "create, stat, utime, stat ========================"
4153
4154 # bug 21114
4155 test_39f() {
4156         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4157
4158         touch $DIR1/$tfile
4159         mtime1=`stat -c %Y $DIR1/$tfile`
4160
4161         sleep 2
4162         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4163
4164         for (( i=0; i < 2; i++ )) ; do
4165                 local mtime2=`stat -c %Y $DIR1/$tfile`
4166                 [ $mtime2 = $TEST_39_MTIME ] || \
4167                         error "mtime($mtime2) is not set to $TEST_39_MTIME"
4168
4169                 cancel_lru_locks $OSC
4170                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4171         done
4172 }
4173 run_test 39f "create, stat, sleep, utime, stat ================="
4174
4175 # bug 11063
4176 test_39g() {
4177         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4178
4179         echo hello >> $DIR1/$tfile
4180         local mtime1=`stat -c %Y $DIR1/$tfile`
4181
4182         sleep 2
4183         chmod o+r $DIR1/$tfile
4184
4185         for (( i=0; i < 2; i++ )) ; do
4186                 local mtime2=`stat -c %Y $DIR1/$tfile`
4187                 [ "$mtime1" = "$mtime2" ] || \
4188                         error "lost mtime: $mtime2, should be $mtime1"
4189
4190                 cancel_lru_locks $OSC
4191                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4192         done
4193 }
4194 run_test 39g "write, chmod, stat ==============================="
4195
4196 # bug 11063
4197 test_39h() {
4198         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4199
4200         touch $DIR1/$tfile
4201         sleep 1
4202
4203         local d1=`date`
4204         echo hello >> $DIR1/$tfile
4205         local mtime1=`stat -c %Y $DIR1/$tfile`
4206
4207         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4208         local d2=`date`
4209         if [ "$d1" != "$d2" ]; then
4210                 echo "write and touch not within one second"
4211         else
4212                 for (( i=0; i < 2; i++ )) ; do
4213                         local mtime2=`stat -c %Y $DIR1/$tfile`
4214                         [ "$mtime2" = $TEST_39_MTIME ] || \
4215                                 error "lost mtime: $mtime2, should be $TEST_39_MTIME"
4216
4217                         cancel_lru_locks $OSC
4218                         if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4219                 done
4220         fi
4221 }
4222 run_test 39h "write, utime within one second, stat ============="
4223
4224 test_39i() {
4225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4226
4227         touch $DIR1/$tfile
4228         sleep 1
4229
4230         echo hello >> $DIR1/$tfile
4231         local mtime1=`stat -c %Y $DIR1/$tfile`
4232
4233         mv $DIR1/$tfile $DIR1/$tfile-1
4234
4235         for (( i=0; i < 2; i++ )) ; do
4236                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4237
4238                 [ "$mtime1" = "$mtime2" ] || \
4239                         error "lost mtime: $mtime2, should be $mtime1"
4240
4241                 cancel_lru_locks $OSC
4242                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4243         done
4244 }
4245 run_test 39i "write, rename, stat =============================="
4246
4247 test_39j() {
4248         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4249
4250         start_full_debug_logging
4251         touch $DIR1/$tfile
4252         sleep 1
4253
4254         #define OBD_FAIL_OSC_DELAY_SETTIME       0x412
4255         lctl set_param fail_loc=0x80000412
4256         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c ||
4257                 error "multiop failed"
4258         local multipid=$!
4259         local mtime1=`stat -c %Y $DIR1/$tfile`
4260
4261         mv $DIR1/$tfile $DIR1/$tfile-1
4262
4263         kill -USR1 $multipid
4264         wait $multipid || error "multiop close failed"
4265
4266         for (( i=0; i < 2; i++ )) ; do
4267                 local mtime2=`stat -c %Y $DIR1/$tfile-1`
4268                 [ "$mtime1" = "$mtime2" ] ||
4269                         error "mtime is lost on close: $mtime2, " \
4270                               "should be $mtime1"
4271
4272                 cancel_lru_locks $OSC
4273                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4274         done
4275         lctl set_param fail_loc=0
4276         stop_full_debug_logging
4277 }
4278 run_test 39j "write, rename, close, stat ======================="
4279
4280 test_39k() {
4281         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4282
4283         touch $DIR1/$tfile
4284         sleep 1
4285
4286         multiop_bg_pause $DIR1/$tfile oO_RDWR:w2097152_c || error "multiop failed"
4287         local multipid=$!
4288         local mtime1=`stat -c %Y $DIR1/$tfile`
4289
4290         touch -m -d @$TEST_39_MTIME $DIR1/$tfile
4291
4292         kill -USR1 $multipid
4293         wait $multipid || error "multiop close failed"
4294
4295         for (( i=0; i < 2; i++ )) ; do
4296                 local mtime2=`stat -c %Y $DIR1/$tfile`
4297
4298                 [ "$mtime2" = $TEST_39_MTIME ] || \
4299                         error "mtime is lost on close: $mtime2, should be $TEST_39_MTIME"
4300
4301                 cancel_lru_locks osc
4302                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4303         done
4304 }
4305 run_test 39k "write, utime, close, stat ========================"
4306
4307 # this should be set to future
4308 TEST_39_ATIME=`date -d "1 year" +%s`
4309
4310 test_39l() {
4311         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4312         remote_mds_nodsh && skip "remote MDS with nodsh"
4313
4314         local atime_diff=$(do_facet $SINGLEMDS \
4315                                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4316         rm -rf $DIR/$tdir
4317         mkdir -p $DIR/$tdir
4318
4319         # test setting directory atime to future
4320         touch -a -d @$TEST_39_ATIME $DIR/$tdir
4321         local atime=$(stat -c %X $DIR/$tdir)
4322         [ "$atime" = $TEST_39_ATIME ] ||
4323                 error "atime is not set to future: $atime, $TEST_39_ATIME"
4324
4325         # test setting directory atime from future to now
4326         local now=$(date +%s)
4327         touch -a -d @$now $DIR/$tdir
4328
4329         atime=$(stat -c %X $DIR/$tdir)
4330         [ "$atime" -eq "$now"  ] ||
4331                 error "atime is not updated from future: $atime, $now"
4332
4333         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=2
4334         sleep 3
4335
4336         # test setting directory atime when now > dir atime + atime_diff
4337         local d1=$(date +%s)
4338         ls $DIR/$tdir
4339         local d2=$(date +%s)
4340         cancel_lru_locks mdc
4341         atime=$(stat -c %X $DIR/$tdir)
4342         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4343                 error "atime is not updated  : $atime, should be $d2"
4344
4345         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=60
4346         sleep 3
4347
4348         # test not setting directory atime when now < dir atime + atime_diff
4349         ls $DIR/$tdir
4350         cancel_lru_locks mdc
4351         atime=$(stat -c %X $DIR/$tdir)
4352         [ "$atime" -ge "$d1" -a "$atime" -le "$d2" ] ||
4353                 error "atime is updated to $atime, should remain $d1<atime<$d2"
4354
4355         do_facet $SINGLEMDS \
4356                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4357 }
4358 run_test 39l "directory atime update ==========================="
4359
4360 test_39m() {
4361         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4362
4363         touch $DIR1/$tfile
4364         sleep 2
4365         local far_past_mtime=$(date -d "May 29 1953" +%s)
4366         local far_past_atime=$(date -d "Dec 17 1903" +%s)
4367
4368         touch -m -d @$far_past_mtime $DIR1/$tfile
4369         touch -a -d @$far_past_atime $DIR1/$tfile
4370
4371         for (( i=0; i < 2; i++ )) ; do
4372                 local timestamps=$(stat -c "%X %Y" $DIR1/$tfile)
4373                 [ "$timestamps" = "$far_past_atime $far_past_mtime" ] || \
4374                         error "atime or mtime set incorrectly"
4375
4376                 cancel_lru_locks $OSC
4377                 if [ $i = 0 ] ; then echo "repeat after cancel_lru_locks"; fi
4378         done
4379 }
4380 run_test 39m "test atime and mtime before 1970"
4381
4382 test_39n() { # LU-3832
4383         remote_mds_nodsh && skip "remote MDS with nodsh"
4384
4385         local atime_diff=$(do_facet $SINGLEMDS \
4386                 lctl get_param -n mdd.*MDT0000*.atime_diff)
4387         local atime0
4388         local atime1
4389         local atime2
4390
4391         do_facet $SINGLEMDS lctl set_param -n mdd.*MDT0000*.atime_diff=1
4392
4393         rm -rf $DIR/$tfile
4394         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 status=noxfer
4395         atime0=$(stat -c %X $DIR/$tfile)
4396
4397         sleep 5
4398         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4399         atime1=$(stat -c %X $DIR/$tfile)
4400
4401         sleep 5
4402         cancel_lru_locks mdc
4403         cancel_lru_locks osc
4404         $MULTIOP $DIR/$tfile oO_RDONLY:O_NOATIME:r4096c
4405         atime2=$(stat -c %X $DIR/$tfile)
4406
4407         do_facet $SINGLEMDS \
4408                 lctl set_param -n mdd.*MDT0000*.atime_diff=$atime_diff
4409
4410         [ "$atime0" -eq "$atime1" ] || error "atime0 $atime0 != atime1 $atime1"
4411         [ "$atime1" -eq "$atime2" ] || error "atime0 $atime0 != atime1 $atime1"
4412 }
4413 run_test 39n "check that O_NOATIME is honored"
4414
4415 test_39o() {
4416         TESTDIR=$DIR/$tdir/$tfile
4417         [ -e $TESTDIR ] && rm -rf $TESTDIR
4418         mkdir -p $TESTDIR
4419         cd $TESTDIR
4420         links1=2
4421         ls
4422         mkdir a b
4423         ls
4424         links2=$(stat -c %h .)
4425         [ $(($links1 + 2)) != $links2 ] &&
4426                 error "wrong links count $(($links1 + 2)) != $links2"
4427         rmdir b
4428         links3=$(stat -c %h .)
4429         [ $(($links1 + 1)) != $links3 ] &&
4430                 error "wrong links count $links1 != $links3"
4431         return 0
4432 }
4433 run_test 39o "directory cached attributes updated after create"
4434
4435 test_39p() {
4436         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
4437
4438         local MDTIDX=1
4439         TESTDIR=$DIR/$tdir/$tdir
4440         [ -e $TESTDIR ] && rm -rf $TESTDIR
4441         test_mkdir -p $TESTDIR
4442         cd $TESTDIR
4443         links1=2
4444         ls
4445         test_mkdir -i $MDTIDX $TESTDIR/remote_dir1
4446         test_mkdir -i $MDTIDX $TESTDIR/remote_dir2
4447         ls
4448         links2=$(stat -c %h .)
4449         [ $(($links1 + 2)) != $links2 ] &&
4450                 error "wrong links count $(($links1 + 2)) != $links2"
4451         rmdir remote_dir2
4452         links3=$(stat -c %h .)
4453         [ $(($links1 + 1)) != $links3 ] &&
4454                 error "wrong links count $links1 != $links3"
4455         return 0
4456 }
4457 run_test 39p "remote directory cached attributes updated after create ========"
4458
4459
4460 test_39q() { # LU-8041
4461         local testdir=$DIR/$tdir
4462         mkdir -p $testdir
4463         multiop_bg_pause $testdir D_c || error "multiop failed"
4464         local multipid=$!
4465         cancel_lru_locks mdc
4466         kill -USR1 $multipid
4467         local atime=$(stat -c %X $testdir)
4468         [ "$atime" -ne 0 ] || error "atime is zero"
4469 }
4470 run_test 39q "close won't zero out atime"
4471
4472 test_40() {
4473         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
4474         $RUNAS $OPENFILE -f O_WRONLY:O_TRUNC $DIR/$tfile &&
4475                 error "openfile O_WRONLY:O_TRUNC $tfile failed"
4476         $CHECKSTAT -t file -s 4096 $DIR/$tfile ||
4477                 error "$tfile is not 4096 bytes in size"
4478 }
4479 run_test 40 "failed open(O_TRUNC) doesn't truncate ============="
4480
4481 test_41() {
4482         # bug 1553
4483         small_write $DIR/f41 18
4484 }
4485 run_test 41 "test small file write + fstat ====================="
4486
4487 count_ost_writes() {
4488         lctl get_param -n ${OSC}.*.stats |
4489                 awk -vwrites=0 '/ost_write/ { writes += $2 } \
4490                         END { printf("%0.0f", writes) }'
4491 }
4492
4493 # decent default
4494 WRITEBACK_SAVE=500
4495 DIRTY_RATIO_SAVE=40
4496 MAX_DIRTY_RATIO=50
4497 BG_DIRTY_RATIO_SAVE=10
4498 MAX_BG_DIRTY_RATIO=25
4499
4500 start_writeback() {
4501         trap 0
4502         # in 2.6, restore /proc/sys/vm/dirty_writeback_centisecs,
4503         # dirty_ratio, dirty_background_ratio
4504         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4505                 sysctl -w vm.dirty_writeback_centisecs=$WRITEBACK_SAVE
4506                 sysctl -w vm.dirty_background_ratio=$BG_DIRTY_RATIO_SAVE
4507                 sysctl -w vm.dirty_ratio=$DIRTY_RATIO_SAVE
4508         else
4509                 # if file not here, we are a 2.4 kernel
4510                 kill -CONT `pidof kupdated`
4511         fi
4512 }
4513
4514 stop_writeback() {
4515         # setup the trap first, so someone cannot exit the test at the
4516         # exact wrong time and mess up a machine
4517         trap start_writeback EXIT
4518         # in 2.6, save and 0 /proc/sys/vm/dirty_writeback_centisecs
4519         if [ -f /proc/sys/vm/dirty_writeback_centisecs ]; then
4520                 WRITEBACK_SAVE=`sysctl -n vm.dirty_writeback_centisecs`
4521                 sysctl -w vm.dirty_writeback_centisecs=0
4522                 sysctl -w vm.dirty_writeback_centisecs=0
4523                 # save and increase /proc/sys/vm/dirty_ratio
4524                 DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_ratio`
4525                 sysctl -w vm.dirty_ratio=$MAX_DIRTY_RATIO
4526                 # save and increase /proc/sys/vm/dirty_background_ratio
4527                 BG_DIRTY_RATIO_SAVE=`sysctl -n vm.dirty_background_ratio`
4528                 sysctl -w vm.dirty_background_ratio=$MAX_BG_DIRTY_RATIO
4529         else
4530                 # if file not here, we are a 2.4 kernel
4531                 kill -STOP `pidof kupdated`
4532         fi
4533 }
4534
4535 # ensure that all stripes have some grant before we test client-side cache
4536 setup_test42() {
4537         for i in `seq -f $DIR/f42-%g 1 $OSTCOUNT`; do
4538                 dd if=/dev/zero of=$i bs=4k count=1
4539                 rm $i
4540         done
4541 }
4542
4543 # Tests 42* verify that our behaviour is correct WRT caching, file closure,
4544 # file truncation, and file removal.
4545 test_42a() {
4546         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4547
4548         setup_test42
4549         cancel_lru_locks $OSC
4550         stop_writeback
4551         sync; sleep 1; sync # just to be safe
4552         BEFOREWRITES=`count_ost_writes`
4553         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur_grant_bytes | grep "[0-9]"
4554         dd if=/dev/zero of=$DIR/f42a bs=1024 count=100
4555         AFTERWRITES=`count_ost_writes`
4556         [ $BEFOREWRITES -eq $AFTERWRITES ] || \
4557                 error "$BEFOREWRITES < $AFTERWRITES"
4558         start_writeback
4559 }
4560 run_test 42a "ensure that we don't flush on close"
4561
4562 test_42b() {
4563         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4564
4565         setup_test42
4566         cancel_lru_locks $OSC
4567         stop_writeback
4568         sync
4569         dd if=/dev/zero of=$DIR/f42b bs=1024 count=100
4570         BEFOREWRITES=$(count_ost_writes)
4571         $MUNLINK $DIR/f42b || error "$MUNLINK $DIR/f42b: $?"
4572         AFTERWRITES=$(count_ost_writes)
4573         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4574                 error "$BEFOREWRITES < $AFTERWRITES on unlink"
4575         fi
4576         BEFOREWRITES=$(count_ost_writes)
4577         sync || error "sync: $?"
4578         AFTERWRITES=$(count_ost_writes)
4579         if [[ $BEFOREWRITES -lt $AFTERWRITES ]]; then
4580                 error "$BEFOREWRITES < $AFTERWRITES on sync"
4581         fi
4582         dmesg | grep 'error from obd_brw_async' && error 'error writing back'
4583         start_writeback
4584         return 0
4585 }
4586 run_test 42b "test destroy of file with cached dirty data ======"
4587
4588 # if these tests just want to test the effect of truncation,
4589 # they have to be very careful.  consider:
4590 # - the first open gets a {0,EOF}PR lock
4591 # - the first write conflicts and gets a {0, count-1}PW
4592 # - the rest of the writes are under {count,EOF}PW
4593 # - the open for truncate tries to match a {0,EOF}PR
4594 #   for the filesize and cancels the PWs.
4595 # any number of fixes (don't get {0,EOF} on open, match
4596 # composite locks, do smarter file size management) fix
4597 # this, but for now we want these tests to verify that
4598 # the cancellation with truncate intent works, so we
4599 # start the file with a full-file pw lock to match against
4600 # until the truncate.
4601 trunc_test() {
4602         test=$1
4603         file=$DIR/$test
4604         offset=$2
4605         cancel_lru_locks $OSC
4606         stop_writeback
4607         # prime the file with 0,EOF PW to match
4608         touch $file
4609         $TRUNCATE $file 0
4610         sync; sync
4611         # now the real test..
4612         dd if=/dev/zero of=$file bs=1024 count=100
4613         BEFOREWRITES=`count_ost_writes`
4614         $TRUNCATE $file $offset
4615         cancel_lru_locks $OSC
4616         AFTERWRITES=`count_ost_writes`
4617         start_writeback
4618 }
4619
4620 test_42c() {
4621         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4622
4623         trunc_test 42c 1024
4624         [ $BEFOREWRITES -eq $AFTERWRITES ] &&
4625                 error "beforewrites $BEFOREWRITES == afterwrites $AFTERWRITES on truncate"
4626         rm $file
4627 }
4628 run_test 42c "test partial truncate of file with cached dirty data"
4629
4630 test_42d() {
4631         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4632
4633         trunc_test 42d 0
4634         [ $BEFOREWRITES -eq $AFTERWRITES ] ||
4635                 error "beforewrites $BEFOREWRITES != afterwrites $AFTERWRITES on truncate"
4636         rm $file
4637 }
4638 run_test 42d "test complete truncate of file with cached dirty data"
4639
4640 test_42e() { # bug22074
4641         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4642
4643         local TDIR=$DIR/${tdir}e
4644         local pages=16 # hardcoded 16 pages, don't change it.
4645         local files=$((OSTCOUNT * 500)) # hopefully 500 files on each OST
4646         local proc_osc0="osc.${FSNAME}-OST0000-osc-[^MDT]*"
4647         local max_dirty_mb
4648         local warmup_files
4649
4650         test_mkdir $DIR/${tdir}e
4651         $LFS setstripe -c 1 $TDIR
4652         createmany -o $TDIR/f $files
4653
4654         max_dirty_mb=$($LCTL get_param -n $proc_osc0/max_dirty_mb)
4655
4656         # we assume that with $OSTCOUNT files, at least one of them will
4657         # be allocated on OST0.
4658         warmup_files=$((OSTCOUNT * max_dirty_mb))
4659         createmany -o $TDIR/w $warmup_files
4660
4661         # write a large amount of data into one file and sync, to get good
4662         # avail_grant number from OST.
4663         for ((i=0; i<$warmup_files; i++)); do
4664                 idx=$($LFS getstripe -i $TDIR/w$i)
4665                 [ $idx -ne 0 ] && continue
4666                 dd if=/dev/zero of=$TDIR/w$i bs="$max_dirty_mb"M count=1
4667                 break
4668         done
4669         [[ $i -gt $warmup_files ]] && error "OST0 is still cold"
4670         sync
4671         $LCTL get_param $proc_osc0/cur_dirty_bytes
4672         $LCTL get_param $proc_osc0/cur_grant_bytes
4673
4674         # create as much dirty pages as we can while not to trigger the actual
4675         # RPCs directly. but depends on the env, VFS may trigger flush during this
4676         # period, hopefully we are good.
4677         for ((i=0; i<$warmup_files; i++)); do
4678                 idx=$($LFS getstripe -i $TDIR/w$i)
4679                 [ $idx -ne 0 ] && continue
4680                 dd if=/dev/zero of=$TDIR/w$i bs=1M count=1 2>/dev/null
4681         done
4682         $LCTL get_param $proc_osc0/cur_dirty_bytes
4683         $LCTL get_param $proc_osc0/cur_grant_bytes
4684
4685         # perform the real test
4686         $LCTL set_param $proc_osc0/rpc_stats 0
4687         for ((;i<$files; i++)); do
4688                 [ $($LFS getstripe -i $TDIR/f$i) -eq 0 ] || continue
4689                 dd if=/dev/zero of=$TDIR/f$i bs=$PAGE_SIZE count=$pages 2>/dev/null
4690         done
4691         sync
4692         $LCTL get_param $proc_osc0/rpc_stats
4693
4694         local percent=0
4695         local have_ppr=false
4696         $LCTL get_param $proc_osc0/rpc_stats |
4697                 while read PPR RRPC RPCT RCUM BAR WRPC WPCT WCUM; do
4698                         # skip lines until we are at the RPC histogram data
4699                         [ "$PPR" == "pages" ] && have_ppr=true && continue
4700                         $have_ppr || continue
4701
4702                         # we only want the percent stat for < 16 pages
4703                         [[ $(echo $PPR | tr -d ':') -ge $pages ]] && break
4704
4705                         percent=$((percent + WPCT))
4706                         if [[ $percent -gt 15 ]]; then
4707                                 error "less than 16-pages write RPCs" \
4708                                       "$percent% > 15%"
4709                                 break
4710                         fi
4711                 done
4712         rm -rf $TDIR
4713 }
4714 run_test 42e "verify sub-RPC writes are not done synchronously"
4715
4716 test_43A() { # was test_43
4717         test_mkdir $DIR/$tdir
4718         cp -p /bin/ls $DIR/$tdir/$tfile
4719         $MULTIOP $DIR/$tdir/$tfile Ow_c &
4720         pid=$!
4721         # give multiop a chance to open
4722         sleep 1
4723
4724         $DIR/$tdir/$tfile && error "execute $DIR/$tdir/$tfile succeeded" || true
4725         kill -USR1 $pid
4726 }
4727 run_test 43A "execution of file opened for write should return -ETXTBSY"
4728
4729 test_43a() {
4730         test_mkdir $DIR/$tdir
4731         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4732         $DIR/$tdir/sleep 60 &
4733         SLEEP_PID=$!
4734         # Make sure exec of $tdir/sleep wins race with truncate
4735         sleep 1
4736         $MULTIOP $DIR/$tdir/sleep Oc && error "expected error, got success"
4737         kill $SLEEP_PID
4738 }
4739 run_test 43a "open(RDWR) of file being executed should return -ETXTBSY"
4740
4741 test_43b() {
4742         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4743
4744         test_mkdir $DIR/$tdir
4745         cp -p $(which sleep) $DIR/$tdir/sleep || error "can't copy"
4746         $DIR/$tdir/sleep 60 &
4747         SLEEP_PID=$!
4748         # Make sure exec of $tdir/sleep wins race with truncate
4749         sleep 1
4750         $TRUNCATE $DIR/$tdir/sleep 0 && error "expected error, got success"
4751         kill $SLEEP_PID
4752 }
4753 run_test 43b "truncate of file being executed should return -ETXTBSY"
4754
4755 test_43c() {
4756         local testdir="$DIR/$tdir"
4757         test_mkdir $testdir
4758         cp $SHELL $testdir/
4759         ( cd $(dirname $SHELL) && md5sum $(basename $SHELL) ) |
4760                 ( cd $testdir && md5sum -c )
4761 }
4762 run_test 43c "md5sum of copy into lustre"
4763
4764 test_44A() { # was test_44
4765         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
4766
4767         dd if=/dev/zero of=$DIR/f1 bs=4k count=1 seek=1023
4768         dd if=$DIR/f1 bs=4k count=1 > /dev/null
4769 }
4770 run_test 44A "zero length read from a sparse stripe"
4771
4772 test_44a() {
4773         local nstripe=$($LCTL lov_getconfig $DIR | grep default_stripe_count: |
4774                 awk '{ print $2 }')
4775         [ -z "$nstripe" ] && skip "can't get stripe info"
4776         [[ $nstripe -gt $OSTCOUNT ]] &&
4777                 skip "Wrong default_stripe_count: $nstripe OSTCOUNT: $OSTCOUNT"
4778
4779         local stride=$($LCTL lov_getconfig $DIR | grep default_stripe_size: |
4780                 awk '{ print $2 }')
4781         if [[ $nstripe -eq 0 || $nstripe -eq -1 ]]; then
4782                 nstripe=$($LCTL lov_getconfig $DIR | grep obd_count: |
4783                         awk '{ print $2 }')
4784         fi
4785
4786         OFFSETS="0 $((stride/2)) $((stride-1))"
4787         for offset in $OFFSETS; do
4788                 for i in $(seq 0 $((nstripe-1))); do
4789                         local GLOBALOFFSETS=""
4790                         # size in Bytes
4791                         local size=$((((i + 2 * $nstripe )*$stride + $offset)))
4792                         local myfn=$DIR/d44a-$size
4793                         echo "--------writing $myfn at $size"
4794                         ll_sparseness_write $myfn $size ||
4795                                 error "ll_sparseness_write"
4796                         GLOBALOFFSETS="$GLOBALOFFSETS $size"
4797                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4798                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4799
4800                         for j in $(seq 0 $((nstripe-1))); do
4801                                 # size in Bytes
4802                                 size=$((((j + $nstripe )*$stride + $offset)))
4803                                 ll_sparseness_write $myfn $size ||
4804                                         error "ll_sparseness_write"
4805                                 GLOBALOFFSETS="$GLOBALOFFSETS $size"
4806                         done
4807                         ll_sparseness_verify $myfn $GLOBALOFFSETS ||
4808                                 error "ll_sparseness_verify $GLOBALOFFSETS"
4809                         rm -f $myfn
4810                 done
4811         done
4812 }
4813 run_test 44a "test sparse pwrite ==============================="
4814
4815 dirty_osc_total() {
4816         tot=0
4817         for d in `lctl get_param -n ${OSC}.*.cur_dirty_bytes`; do
4818                 tot=$(($tot + $d))
4819         done
4820         echo $tot
4821 }
4822 do_dirty_record() {
4823         before=`dirty_osc_total`
4824         echo executing "\"$*\""
4825         eval $*
4826         after=`dirty_osc_total`
4827         echo before $before, after $after
4828 }
4829 test_45() {
4830         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4831
4832         f="$DIR/f45"
4833         # Obtain grants from OST if it supports it
4834         echo blah > ${f}_grant
4835         stop_writeback
4836         sync
4837         do_dirty_record "echo blah > $f"
4838         [[ $before -eq $after ]] && error "write wasn't cached"
4839         do_dirty_record "> $f"
4840         [[ $before -gt $after ]] || error "truncate didn't lower dirty count"
4841         do_dirty_record "echo blah > $f"
4842         [[ $before -eq $after ]] && error "write wasn't cached"
4843         do_dirty_record "sync"
4844         [[ $before -gt $after ]] || error "writeback didn't lower dirty count"
4845         do_dirty_record "echo blah > $f"
4846         [[ $before -eq $after ]] && error "write wasn't cached"
4847         do_dirty_record "cancel_lru_locks osc"
4848         [[ $before -gt $after ]] ||
4849                 error "lock cancellation didn't lower dirty count"
4850         start_writeback
4851 }
4852 run_test 45 "osc io page accounting ============================"
4853
4854 # in a 2 stripe file (lov.sh), page 1023 maps to page 511 in its object.  this
4855 # test tickles a bug where re-dirtying a page was failing to be mapped to the
4856 # objects offset and an assert hit when an rpc was built with 1023's mapped
4857 # offset 511 and 511's raw 511 offset. it also found general redirtying bugs.
4858 test_46() {
4859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4860
4861         f="$DIR/f46"
4862         stop_writeback
4863         sync
4864         dd if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4865         sync
4866         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=1023 count=1
4867         dd conv=notrunc if=/dev/zero of=$f bs=$PAGE_SIZE seek=511 count=1
4868         sync
4869         start_writeback
4870 }
4871 run_test 46 "dirtying a previously written page ================"
4872
4873 # test_47 is removed "Device nodes check" is moved to test_28
4874
4875 test_48a() { # bug 2399
4876         [ "$mds1_FSTYPE" = "zfs" ] &&
4877         [ $MDS1_VERSION -lt $(version_code 2.3.63) ] &&
4878                 skip "MDS prior to 2.3.63 handle ZFS dir .. incorrectly"
4879
4880         test_mkdir $DIR/$tdir
4881         cd $DIR/$tdir
4882         mv $DIR/$tdir $DIR/$tdir.new || error "move directory failed"
4883         test_mkdir $DIR/$tdir
4884         touch foo || error "'touch foo' failed after recreating cwd"
4885         test_mkdir bar
4886         touch .foo || error "'touch .foo' failed after recreating cwd"
4887         test_mkdir .bar
4888         ls . > /dev/null || error "'ls .' failed after recreating cwd"
4889         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4890         cd . || error "'cd .' failed after recreating cwd"
4891         mkdir . && error "'mkdir .' worked after recreating cwd"
4892         rmdir . && error "'rmdir .' worked after recreating cwd"
4893         ln -s . baz || error "'ln -s .' failed after recreating cwd"
4894         cd .. || error "'cd ..' failed after recreating cwd"
4895 }
4896 run_test 48a "Access renamed working dir (should return errors)="
4897
4898 test_48b() { # bug 2399
4899         rm -rf $DIR/$tdir
4900         test_mkdir $DIR/$tdir
4901         cd $DIR/$tdir
4902         rmdir $DIR/$tdir || error "remove cwd $DIR/$tdir failed"
4903         touch foo && error "'touch foo' worked after removing cwd"
4904         mkdir foo && error "'mkdir foo' worked after removing cwd"
4905         touch .foo && error "'touch .foo' worked after removing cwd"
4906         mkdir .foo && error "'mkdir .foo' worked after removing cwd"
4907         ls . > /dev/null && error "'ls .' worked after removing cwd"
4908         ls .. > /dev/null || error "'ls ..' failed after removing cwd"
4909         mkdir . && error "'mkdir .' worked after removing cwd"
4910         rmdir . && error "'rmdir .' worked after removing cwd"
4911         ln -s . foo && error "'ln -s .' worked after removing cwd"
4912         cd .. || echo "'cd ..' failed after removing cwd `pwd`"  #bug 3517
4913 }
4914 run_test 48b "Access removed working dir (should return errors)="
4915
4916 test_48c() { # bug 2350
4917         #lctl set_param debug=-1
4918         #set -vx
4919         rm -rf $DIR/$tdir
4920         test_mkdir -p $DIR/$tdir/dir
4921         cd $DIR/$tdir/dir
4922         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4923         $TRACE touch foo && error "touch foo worked after removing cwd"
4924         $TRACE mkdir foo && error "'mkdir foo' worked after removing cwd"
4925         touch .foo && error "touch .foo worked after removing cwd"
4926         mkdir .foo && error "mkdir .foo worked after removing cwd"
4927         $TRACE ls . && error "'ls .' worked after removing cwd"
4928         $TRACE ls .. || error "'ls ..' failed after removing cwd"
4929         $TRACE mkdir . && error "'mkdir .' worked after removing cwd"
4930         $TRACE rmdir . && error "'rmdir .' worked after removing cwd"
4931         $TRACE ln -s . foo && error "'ln -s .' worked after removing cwd"
4932         $TRACE cd .. || echo "'cd ..' failed after removing cwd `pwd`" #bug 3415
4933 }
4934 run_test 48c "Access removed working subdir (should return errors)"
4935
4936 test_48d() { # bug 2350
4937         #lctl set_param debug=-1
4938         #set -vx
4939         rm -rf $DIR/$tdir
4940         test_mkdir -p $DIR/$tdir/dir
4941         cd $DIR/$tdir/dir
4942         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4943         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4944         $TRACE touch foo && error "'touch foo' worked after removing parent"
4945         $TRACE mkdir foo && error "mkdir foo worked after removing parent"
4946         touch .foo && error "'touch .foo' worked after removing parent"
4947         mkdir .foo && error "mkdir .foo worked after removing parent"
4948         $TRACE ls . && error "'ls .' worked after removing parent"
4949         $TRACE ls .. && error "'ls ..' worked after removing parent"
4950         $TRACE mkdir . && error "'mkdir .' worked after removing parent"
4951         $TRACE rmdir . && error "'rmdir .' worked after removing parent"
4952         $TRACE ln -s . foo && error "'ln -s .' worked after removing parent"
4953         true
4954 }
4955 run_test 48d "Access removed parent subdir (should return errors)"
4956
4957 test_48e() { # bug 4134
4958         #lctl set_param debug=-1
4959         #set -vx
4960         rm -rf $DIR/$tdir
4961         test_mkdir -p $DIR/$tdir/dir
4962         cd $DIR/$tdir/dir
4963         $TRACE rmdir $DIR/$tdir/dir || error "remove cwd $DIR/$tdir/dir failed"
4964         $TRACE rmdir $DIR/$tdir || error "remove parent $DIR/$tdir failed"
4965         $TRACE touch $DIR/$tdir || error "'touch $DIR/$tdir' failed"
4966         $TRACE chmod +x $DIR/$tdir || error "'chmod +x $DIR/$tdir' failed"
4967         # On a buggy kernel addition of "touch foo" after cd .. will
4968         # produce kernel oops in lookup_hash_it
4969         touch ../foo && error "'cd ..' worked after recreate parent"
4970         cd $DIR
4971         $TRACE rm $DIR/$tdir || error "rm '$DIR/$tdir' failed"
4972 }
4973 run_test 48e "Access to recreated parent subdir (should return errors)"
4974
4975 test_49() { # LU-1030
4976         [ $PARALLEL == "yes" ] && skip "skip parallel run"
4977         remote_ost_nodsh && skip "remote OST with nodsh"
4978
4979         # get ost1 size - lustre-OST0000
4980         ost1_size=$(do_facet ost1 $LFS df | grep ${ost1_svc} |
4981                 awk '{ print $4 }')
4982         # write 800M at maximum
4983         [[ $ost1_size -lt 2 ]] && ost1_size=2
4984         [[ $ost1_size -gt 819200 ]] && ost1_size=819200
4985
4986         $LFS setstripe -c 1 -i 0 $DIR/$tfile
4987         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((ost1_size >> 2)) &
4988         local dd_pid=$!
4989
4990         # change max_pages_per_rpc while writing the file
4991         local osc1_mppc=osc.$(get_osc_import_name client ost1).max_pages_per_rpc
4992         local orig_mppc=$($LCTL get_param -n $osc1_mppc)
4993         # loop until dd process exits
4994         while ps ax -opid | grep -wq $dd_pid; do
4995                 $LCTL set_param $osc1_mppc=$((RANDOM % 256 + 1))
4996                 sleep $((RANDOM % 5 + 1))
4997         done
4998         # restore original max_pages_per_rpc
4999         $LCTL set_param $osc1_mppc=$orig_mppc
5000         rm $DIR/$tfile || error "rm $DIR/$tfile failed"
5001 }
5002 run_test 49 "Change max_pages_per_rpc won't break osc extent"
5003
5004 test_50() {
5005         # bug 1485
5006         test_mkdir $DIR/$tdir
5007         cd $DIR/$tdir
5008         ls /proc/$$/cwd || error "ls /proc/$$/cwd failed"
5009 }
5010 run_test 50 "special situations: /proc symlinks  ==============="
5011
5012 test_51a() {    # was test_51
5013         # bug 1516 - create an empty entry right after ".." then split dir
5014         test_mkdir -c1 $DIR/$tdir
5015         touch $DIR/$tdir/foo
5016         $MCREATE $DIR/$tdir/bar
5017         rm $DIR/$tdir/foo
5018         createmany -m $DIR/$tdir/longfile 201
5019         FNUM=202
5020         while [[ $(ls -sd $DIR/$tdir | awk '{ print $1 }') -eq 4 ]]; do
5021                 $MCREATE $DIR/$tdir/longfile$FNUM
5022                 FNUM=$(($FNUM + 1))
5023                 echo -n "+"
5024         done
5025         echo
5026         ls -l $DIR/$tdir > /dev/null || error "ls -l $DIR/$tdir failed"
5027 }
5028 run_test 51a "special situations: split htree with empty entry =="
5029
5030 cleanup_print_lfs_df () {
5031         trap 0
5032         $LFS df
5033         $LFS df -i
5034 }
5035
5036 test_51b() {
5037         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5038
5039         local dir=$DIR/$tdir
5040         local nrdirs=$((65536 + 100))
5041
5042         # cleanup the directory
5043         rm -fr $dir
5044
5045         test_mkdir -c1 $dir
5046
5047         $LFS df
5048         $LFS df -i
5049         local mdtidx=$(printf "%04x" $($LFS getstripe -m $dir))
5050         local numfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.filesfree)
5051         [[ $numfree -lt $nrdirs ]] &&
5052                 skip "not enough free inodes ($numfree) on MDT$mdtidx"
5053
5054         # need to check free space for the directories as well
5055         local blkfree=$(lctl get_param -n mdc.$FSNAME-MDT$mdtidx*.kbytesavail)
5056         numfree=$(( blkfree / $(fs_inode_ksize) ))
5057         [[ $numfree -lt $nrdirs ]] && skip "not enough blocks ($numfree)"
5058
5059         trap cleanup_print_lfs_df EXIT
5060
5061         # create files
5062         createmany -d $dir/d $nrdirs || {
5063                 unlinkmany $dir/d $nrdirs
5064                 error "failed to create $nrdirs subdirs in MDT$mdtidx:$dir"
5065         }
5066
5067         # really created :
5068         nrdirs=$(ls -U $dir | wc -l)
5069
5070         # unlink all but 100 subdirectories, then check it still works
5071         local left=100
5072         local delete=$((nrdirs - left))
5073
5074         $LFS df
5075         $LFS df -i
5076
5077         # for ldiskfs the nlink count should be 1, but this is OSD specific
5078         # and so this is listed for informational purposes only
5079         echo "nlink before: $(stat -c %h $dir), created before: $nrdirs"
5080         unlinkmany -d $dir/d $delete ||
5081                 error "unlink of first $delete subdirs failed"
5082
5083         echo "nlink between: $(stat -c %h $dir)"
5084         local found=$(ls -U $dir | wc -l)
5085         [ $found -ne $left ] &&
5086                 error "can't find subdirs: found only $found, expected $left"
5087
5088         unlinkmany -d $dir/d $delete $left ||
5089                 error "unlink of second $left subdirs failed"
5090         # regardless of whether the backing filesystem tracks nlink accurately
5091         # or not, the nlink count shouldn't be more than "." and ".." here
5092         local after=$(stat -c %h $dir)
5093         [[ $after -gt 2 ]] && error "nlink after: $after > 2" ||
5094                 echo "nlink after: $after"
5095
5096         cleanup_print_lfs_df
5097 }
5098 run_test 51b "exceed 64k subdirectory nlink limit on create, verify unlink"
5099
5100 test_51d() {
5101         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5102         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
5103
5104         test_mkdir $DIR/$tdir
5105         createmany -o $DIR/$tdir/t- 1000
5106         $LFS getstripe $DIR/$tdir > $TMP/$tfile
5107         for N in $(seq 0 $((OSTCOUNT - 1))); do
5108                 OBJS[$N]=$(awk -vobjs=0 '($1 == '$N') { objs += 1 } \
5109                         END { printf("%0.0f", objs) }' $TMP/$tfile)
5110                 OBJS0[$N]=$(grep -A 1 idx $TMP/$tfile | awk -vobjs=0 \
5111                         '($1 == '$N') { objs += 1 } \
5112                         END { printf("%0.0f", objs) }')
5113                 log "OST$N has ${OBJS[$N]} objects, ${OBJS0[$N]} are index 0"
5114         done
5115         unlinkmany $DIR/$tdir/t- 1000
5116
5117         NLAST=0
5118         for N in $(seq 1 $((OSTCOUNT - 1))); do
5119                 [[ ${OBJS[$N]} -lt $((${OBJS[$NLAST]} - 20)) ]] &&
5120                         error "OST $N has less objects vs OST $NLAST" \
5121                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5122                 [[ ${OBJS[$N]} -gt $((${OBJS[$NLAST]} + 20)) ]] &&
5123                         error "OST $N has less objects vs OST $NLAST" \
5124                               " (${OBJS[$N]} < ${OBJS[$NLAST]}"
5125
5126                 [[ ${OBJS0[$N]} -lt $((${OBJS0[$NLAST]} - 20)) ]] &&
5127                         error "OST $N has less #0 objects vs OST $NLAST" \
5128                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5129                 [[ ${OBJS0[$N]} -gt $((${OBJS0[$NLAST]} + 20)) ]] &&
5130                         error "OST $N has less #0 objects vs OST $NLAST" \
5131                               " (${OBJS0[$N]} < ${OBJS0[$NLAST]}"
5132                 NLAST=$N
5133         done
5134         rm -f $TMP/$tfile
5135 }
5136 run_test 51d "check object distribution"
5137
5138 test_51e() {
5139         if [ "$mds1_FSTYPE" != ldiskfs ]; then
5140                 skip_env "ldiskfs only test"
5141         fi
5142
5143         test_mkdir -c1 $DIR/$tdir
5144         test_mkdir -c1 $DIR/$tdir/d0
5145
5146         touch $DIR/$tdir/d0/foo
5147         createmany -l $DIR/$tdir/d0/foo $DIR/$tdir/d0/f- 65001 &&
5148                 error "file exceed 65000 nlink limit!"
5149         unlinkmany $DIR/$tdir/d0/f- 65001
5150         return 0
5151 }
5152 run_test 51e "check file nlink limit"
5153
5154 test_51f() {
5155         test_mkdir $DIR/$tdir
5156
5157         local max=100000
5158         local ulimit_old=$(ulimit -n)
5159         local spare=20 # number of spare fd's for scripts/libraries, etc.
5160         local mdt=$($LFS getstripe -m $DIR/$tdir)
5161         local numfree=$($LFS df -i $DIR/$tdir | awk '/MDT:'$mdt'/ { print $4 }')
5162
5163         echo "MDT$mdt numfree=$numfree, max=$max"
5164         [[ $numfree -gt $max ]] && numfree=$max || numfree=$((numfree * 7 / 8))
5165         if [ $((numfree + spare)) -gt $ulimit_old ]; then
5166                 while ! ulimit -n $((numfree + spare)); do
5167                         numfree=$((numfree * 3 / 4))
5168                 done
5169                 echo "changed ulimit from $ulimit_old to $((numfree + spare))"
5170         else
5171                 echo "left ulimit at $ulimit_old"
5172         fi
5173
5174         createmany -o -k -t 120 $DIR/$tdir/f $numfree || {
5175                 unlinkmany $DIR/$tdir/f $numfree
5176                 error "create+open $numfree files in $DIR/$tdir failed"
5177         }
5178         ulimit -n $ulimit_old
5179
5180         # if createmany exits at 120s there will be fewer than $numfree files
5181         unlinkmany $DIR/$tdir/f $numfree || true
5182 }
5183 run_test 51f "check many open files limit"
5184
5185 test_52a() {
5186         [ -f $DIR/$tdir/foo ] && chattr -a $DIR/$tdir/foo
5187         test_mkdir $DIR/$tdir
5188         touch $DIR/$tdir/foo
5189         chattr +a $DIR/$tdir/foo || error "chattr +a failed"
5190         echo bar >> $DIR/$tdir/foo || error "append bar failed"
5191         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5192         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5193         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5194                                         error "link worked"
5195         echo foo >> $DIR/$tdir/foo || error "append foo failed"
5196         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5197         lsattr $DIR/$tdir/foo | egrep -q "^-+a[-e]+ $DIR/$tdir/foo" ||
5198                                                      error "lsattr"
5199         chattr -a $DIR/$tdir/foo || error "chattr -a failed"
5200         cp -r $DIR/$tdir $TMP/
5201         rm -fr $DIR/$tdir $TMP/$tdir || error "cleanup rm failed"
5202 }
5203 run_test 52a "append-only flag test (should return errors)"
5204
5205 test_52b() {
5206         [ -f $DIR/$tdir/foo ] && chattr -i $DIR/$tdir/foo
5207         test_mkdir $DIR/$tdir
5208         touch $DIR/$tdir/foo
5209         chattr +i $DIR/$tdir/foo || error "chattr +i failed"
5210         cat test > $DIR/$tdir/foo && error "cat test worked"
5211         cp /etc/hosts $DIR/$tdir/foo && error "cp worked"
5212         rm -f $DIR/$tdir/foo 2>/dev/null && error "rm worked"
5213         link $DIR/$tdir/foo $DIR/$tdir/foo_link 2>/dev/null &&
5214                                         error "link worked"
5215         echo foo >> $DIR/$tdir/foo && error "echo worked"
5216         mrename $DIR/$tdir/foo $DIR/$tdir/foo_ren && error "rename worked"
5217         [ -f $DIR/$tdir/foo ] || error "$tdir/foo is not a file"
5218         [ -f $DIR/$tdir/foo_ren ] && error "$tdir/foo_ren is not a file"
5219         lsattr $DIR/$tdir/foo | egrep -q "^-+i[-e]+ $DIR/$tdir/foo" ||
5220                                                         error "lsattr"
5221         chattr -i $DIR/$tdir/foo || error "chattr failed"
5222
5223         rm -fr $DIR/$tdir || error "unable to remove $DIR/$tdir"
5224 }
5225 run_test 52b "immutable flag test (should return errors) ======="
5226
5227 test_53() {
5228         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5229         remote_mds_nodsh && skip "remote MDS with nodsh"
5230         remote_ost_nodsh && skip "remote OST with nodsh"
5231
5232         local param
5233         local param_seq
5234         local ostname
5235         local mds_last
5236         local mds_last_seq
5237         local ost_last
5238         local ost_last_seq
5239         local ost_last_id
5240         local ostnum
5241         local node
5242         local found=false
5243         local support_last_seq=true
5244
5245         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
5246                 support_last_seq=false
5247
5248         # only test MDT0000
5249         local mdtosc=$(get_mdtosc_proc_path $SINGLEMDS)
5250         local value
5251         for value in $(do_facet $SINGLEMDS \
5252                        $LCTL get_param osp.$mdtosc.prealloc_last_id) ; do
5253                 param=$(echo ${value[0]} | cut -d "=" -f1)
5254                 ostname=$(echo $param | cut -d "." -f2 | cut -d - -f 1-2)
5255
5256                 if $support_last_seq; then
5257                         param_seq=$(echo $param |
5258                                 sed -e s/prealloc_last_id/prealloc_last_seq/g)
5259                         mds_last_seq=$(do_facet $SINGLEMDS \
5260                                        $LCTL get_param -n $param_seq)
5261                 fi
5262                 mds_last=$(do_facet $SINGLEMDS $LCTL get_param -n $param)
5263
5264                 ostnum=$(index_from_ostuuid ${ostname}_UUID)
5265                 node=$(facet_active_host ost$((ostnum+1)))
5266                 param="obdfilter.$ostname.last_id"
5267                 for ost_last in $(do_node $node $LCTL get_param -n $param) ; do
5268                         echo "$ostname.last_id=$ost_last; MDS.last_id=$mds_last"
5269                         ost_last_id=$ost_last
5270
5271                         if $support_last_seq; then
5272                                 ost_last_id=$(echo $ost_last |
5273                                               awk -F':' '{print $2}' |
5274                                               sed -e "s/^0x//g")
5275                                 ost_last_seq=$(echo $ost_last |
5276                                                awk -F':' '{print $1}')
5277                                 [[ $ost_last_seq = $mds_last_seq ]] || continue
5278                         fi
5279
5280                         if [[ $ost_last_id != $mds_last ]]; then
5281                                 error "$ost_last_id != $mds_last"
5282                         else
5283                                 found=true
5284                                 break
5285                         fi
5286                 done
5287         done
5288         $found || error "can not match last_seq/last_id for $mdtosc"
5289         return 0
5290 }
5291 run_test 53 "verify that MDS and OSTs agree on pre-creation ===="
5292
5293 test_54a() {
5294         perl -MSocket -e ';' || skip "no Socket perl module installed"
5295
5296         $SOCKETSERVER $DIR/socket ||
5297                 error "$SOCKETSERVER $DIR/socket failed: $?"
5298         $SOCKETCLIENT $DIR/socket ||
5299                 error "$SOCKETCLIENT $DIR/socket failed: $?"
5300         $MUNLINK $DIR/socket || error "$MUNLINK $DIR/socket failed: $?"
5301 }
5302 run_test 54a "unix domain socket test =========================="
5303
5304 test_54b() {
5305         f="$DIR/f54b"
5306         mknod $f c 1 3
5307         chmod 0666 $f
5308         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1
5309 }
5310 run_test 54b "char device works in lustre ======================"
5311
5312 find_loop_dev() {
5313         [ -b /dev/loop/0 ] && LOOPBASE=/dev/loop/
5314         [ -b /dev/loop0 ] && LOOPBASE=/dev/loop
5315         [ -z "$LOOPBASE" ] && echo "/dev/loop/0 and /dev/loop0 gone?" && return
5316
5317         for i in $(seq 3 7); do
5318                 losetup $LOOPBASE$i > /dev/null 2>&1 && continue
5319                 LOOPDEV=$LOOPBASE$i
5320                 LOOPNUM=$i
5321                 break
5322         done
5323 }
5324
5325 cleanup_54c() {
5326         local rc=0
5327         loopdev="$DIR/loop54c"
5328
5329         trap 0
5330         $UMOUNT $DIR/$tdir || rc=$?
5331         losetup -d $loopdev || true
5332         losetup -d $LOOPDEV || true
5333         rm -rf $loopdev $DIR/$tfile $DIR/$tdir
5334         return $rc
5335 }
5336
5337 test_54c() {
5338         [ $PARALLEL == "yes" ] && skip "skip parallel run"
5339
5340         loopdev="$DIR/loop54c"
5341
5342         find_loop_dev
5343         [ -z "$LOOPNUM" ] && skip_env "couldn't find empty loop device"
5344         trap cleanup_54c EXIT
5345         mknod $loopdev b 7 $LOOPNUM
5346         echo "make a loop file system with $DIR/$tfile on $loopdev ($LOOPNUM)."
5347         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE seek=1024 count=1 > /dev/null
5348         losetup $loopdev $DIR/$tfile ||
5349                 error "can't set up $loopdev for $DIR/$tfile"
5350         mkfs.ext2 $loopdev || error "mke2fs on $loopdev"
5351         test_mkdir $DIR/$tdir
5352         mount -t ext2 $loopdev $DIR/$tdir ||
5353                 error "error mounting $loopdev on $DIR/$tdir"
5354         dd if=/dev/zero of=$DIR/$tdir/tmp bs=$PAGE_SIZE count=30 ||
5355                 error "dd write"
5356         df $DIR/$tdir
5357         dd if=$DIR/$tdir/tmp of=/dev/zero bs=$PAGE_SIZE count=30 ||
5358                 error "dd read"
5359         cleanup_54c
5360 }
5361 run_test 54c "block device works in lustre ====================="
5362
5363 test_54d() {
5364         f="$DIR/f54d"
5365         string="aaaaaa"
5366         mknod $f p
5367         [ "$string" = $(echo $string > $f | cat $f) ] || error "$f != $string"
5368 }
5369 run_test 54d "fifo device works in lustre ======================"
5370
5371 test_54e() {
5372         f="$DIR/f54e"
5373         string="aaaaaa"
5374         cp -aL /dev/console $f
5375         echo $string > $f || error "echo $string to $f failed"
5376 }
5377 run_test 54e "console/tty device works in lustre ======================"
5378
5379 test_56a() {
5380         local numfiles=3
5381         local dir=$DIR/$tdir
5382
5383         rm -rf $dir
5384         test_mkdir -p $dir/dir
5385         for i in $(seq $numfiles); do
5386                 touch $dir/file$i
5387                 touch $dir/dir/file$i
5388         done
5389
5390         local numcomp=$($LFS getstripe --component-count $dir)
5391
5392         [[ $numcomp == 0 ]] && numcomp=1
5393
5394         # test lfs getstripe with --recursive
5395         local filenum=$($LFS getstripe -r $dir | egrep -c "obdidx|l_ost_idx")
5396
5397         [[ $filenum -eq $((numfiles * 2)) ]] ||
5398                 error "$LFS getstripe -r: found $filenum != $((numfiles * 2))"
5399         filenum=$($LFS getstripe $dir | egrep -c "obdidx|l_ost_idx")
5400         [[ $filenum -eq $numfiles ]] ||
5401                 error "$LFS getstripe $dir: found $filenum, not $numfiles"
5402         echo "$LFS getstripe showed obdidx or l_ost_idx"
5403
5404         # test lfs getstripe with file instead of dir
5405         filenum=$($LFS getstripe $dir/file1 | egrep -c "obdidx|l_ost_idx")
5406         [[ $filenum -eq 1 ]] ||
5407                 error "$LFS getstripe $dir/file1: found $filenum, not 1"
5408         echo "$LFS getstripe file1 passed"
5409
5410         #test lfs getstripe with --verbose
5411         filenum=$($LFS getstripe --verbose $dir | grep -c lmm_magic)
5412         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5413                 error "$LFS getstripe --verbose $dir: "\
5414                       "got $filenum want $((numfiles * numcomp)) lmm_magic"
5415         [[ $($LFS getstripe $dir | grep -c lmm_magic) -eq 0 ]] ||
5416                 error "$LFS getstripe $dir: showed lmm_magic"
5417
5418         #test lfs getstripe with -v prints lmm_fid
5419         filenum=$($LFS getstripe -v $dir | grep -c lmm_fid)
5420         [[ $filenum -eq $((numfiles * numcomp)) ]] ||
5421                 error "$LFS getstripe -v $dir: "\
5422                       "got $filenum want $((numfiles * numcomp)) lmm_fid"
5423         [[ $($LFS getstripe $dir | grep -c lmm_fid) -eq 0 ]] ||
5424                 error "$LFS getstripe $dir: showed lmm_fid by default"
5425         echo "$LFS getstripe --verbose passed"
5426
5427         #check for FID information
5428         local fid1=$($LFS getstripe --fid $dir/file1)
5429         local fid2=$($LFS getstripe --verbose $dir/file1 |
5430                      awk '/lmm_fid: / { print $2; exit; }')
5431         local fid3=$($LFS path2fid $dir/file1)
5432
5433         [ "$fid1" != "$fid2" ] &&
5434                 error "getstripe --fid '$fid1' != getstripe --verbose '$fid2'"
5435         [ "$fid1" != "$fid3" ] &&
5436                 error "getstripe --fid '$fid1' != lfs path2fid '$fid3'"
5437         echo "$LFS getstripe --fid passed"
5438
5439         #test lfs getstripe with --obd
5440         $LFS getstripe --obd wrong_uuid $dir 2>&1 | grep -q "unknown obduuid" ||
5441                 error "$LFS getstripe --obd wrong_uuid: should return error"
5442
5443         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
5444
5445         local ostidx=1
5446         local obduuid=$(ostuuid_from_index $ostidx)
5447         local found=$($LFS getstripe -r --obd $obduuid $dir |
5448                 grep 'lmm_stripe_offset:' | grep -c " $ostidx\$")
5449
5450         filenum=$($LFS getstripe -ir $dir | grep -c "^$ostidx\$")
5451         [[ $($LFS getstripe -id $dir) -ne $ostidx ]] ||
5452                 ((filenum--))
5453         [[ $($LFS getstripe -id $dir/dir) -ne $ostidx ]] ||
5454                 ((filenum--))
5455
5456         [[ $found -eq $filenum ]] ||
5457                 error "$LFS getstripe --obd: found $found expect $filenum"
5458         [[ $($LFS getstripe -r -v --obd $obduuid $dir |
5459                 sed '/^[         ]*'${ostidx}'[  ]/d' |
5460                 sed -n '/^[      ]*[0-9][0-9]*[  ]/p' | wc -l) -eq 0 ]] ||
5461                 error "$LFS getstripe --obd: should not show file on other obd"
5462         echo "$LFS getstripe --obd passed"
5463 }
5464 run_test 56a "check $LFS getstripe"
5465
5466 test_56b() {
5467         local dir=$DIR/$tdir
5468         local numdirs=3
5469
5470         test_mkdir $dir
5471         for i in $(seq $numdirs); do
5472                 test_mkdir $dir/dir$i
5473         done
5474
5475         # test lfs getdirstripe default mode is non-recursion, which is
5476         # different from lfs getstripe
5477         local dircnt=$($LFS getdirstripe $dir | grep -c lmv_stripe_count)
5478
5479         [[ $dircnt -eq 1 ]] ||
5480                 error "$LFS getdirstripe: found $dircnt, not 1"
5481         dircnt=$($LFS getdirstripe --recursive $dir |
5482                 grep -c lmv_stripe_count)
5483         [[ $dircnt -eq $((numdirs + 1)) ]] ||
5484                 error "$LFS getdirstripe -r: $dircnt, != $((numdirs + 1))"
5485 }
5486 run_test 56b "check $LFS getdirstripe"
5487
5488 test_56c() {
5489         remote_ost_nodsh && skip "remote OST with nodsh"
5490
5491         local ost_idx=0
5492         local ost_name=$(ostname_from_index $ost_idx)
5493         local old_status=$(ost_dev_status $ost_idx)
5494
5495         [[ -z "$old_status" ]] ||
5496                 skip_env "OST $ost_name is in $old_status status"
5497
5498         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=1
5499         sleep_maxage
5500
5501         local new_status=$(ost_dev_status $ost_idx)
5502
5503         [[ "$new_status" = "D" ]] ||
5504                 error "OST $ost_name is in status of '$new_status', not 'D'"
5505
5506         do_facet ost1 $LCTL set_param -n obdfilter.$ost_name.degraded=0
5507         sleep_maxage
5508
5509         new_status=$(ost_dev_status $ost_idx)
5510         [[ -z "$new_status" ]] ||
5511                 error "OST $ost_name is in status of '$new_status', not ''"
5512 }
5513 run_test 56c "check 'lfs df' showing device status"
5514
5515 NUMFILES=3
5516 NUMDIRS=3
5517 setup_56() {
5518         local local_tdir="$1"
5519         local local_numfiles="$2"
5520         local local_numdirs="$3"
5521         local dir_params="$4"
5522         local dir_stripe_params="$5"
5523
5524         if [ ! -d "$local_tdir" ] ; then
5525                 test_mkdir -p $dir_stripe_params $local_tdir
5526                 [ "$dir_params" ] && $LFS setstripe $dir_params $local_tdir
5527                 for i in $(seq $local_numfiles) ; do
5528                         touch $local_tdir/file$i
5529                 done
5530                 for i in $(seq $local_numdirs) ; do
5531                         test_mkdir $dir_stripe_params $local_tdir/dir$i
5532                         for j in $(seq $local_numfiles) ; do
5533                                 touch $local_tdir/dir$i/file$j
5534                         done
5535                 done
5536         fi
5537 }
5538
5539 setup_56_special() {
5540         local local_tdir=$1
5541         local local_numfiles=$2
5542         local local_numdirs=$3
5543
5544         setup_56 $local_tdir $local_numfiles $local_numdirs
5545
5546         if [ ! -e "$local_tdir/loop${local_numfiles}b" ] ; then
5547                 for i in $(seq $local_numfiles) ; do
5548                         mknod $local_tdir/loop${i}b b 7 $i
5549                         mknod $local_tdir/null${i}c c 1 3
5550                         ln -s $local_tdir/file1 $local_tdir/link${i}
5551                 done
5552                 for i in $(seq $local_numdirs) ; do
5553                         mknod $local_tdir/dir$i/loop${i}b b 7 $i
5554                         mknod $local_tdir/dir$i/null${i}c c 1 3
5555                         ln -s $local_tdir/dir$i/file1 $local_tdir/dir$i/link${i}
5556                 done
5557         fi
5558 }
5559
5560 test_56g() {
5561         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5562         local expected=$(($NUMDIRS + 2))
5563
5564         setup_56 $dir $NUMFILES $NUMDIRS
5565
5566         # test lfs find with -name
5567         for i in $(seq $NUMFILES) ; do
5568                 local nums=$($LFS find -name "*$i" $dir | wc -l)
5569
5570                 [ $nums -eq $expected ] ||
5571                         error "lfs find -name '*$i' $dir wrong: "\
5572                               "found $nums, expected $expected"
5573         done
5574 }
5575 run_test 56g "check lfs find -name"
5576
5577 test_56h() {
5578         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5579         local expected=$(((NUMDIRS + 1) * (NUMFILES - 1) + NUMFILES))
5580
5581         setup_56 $dir $NUMFILES $NUMDIRS
5582
5583         # test lfs find with ! -name
5584         for i in $(seq $NUMFILES) ; do
5585                 local nums=$($LFS find ! -name "*$i" $dir | wc -l)
5586
5587                 [ $nums -eq $expected ] ||
5588                         error "lfs find ! -name '*$i' $dir wrong: "\
5589                               "found $nums, expected $expected"
5590         done
5591 }
5592 run_test 56h "check lfs find ! -name"
5593
5594 test_56i() {
5595         local dir=$DIR/$tdir
5596
5597         test_mkdir $dir
5598
5599         local cmd="$LFS find -ost $(ostuuid_from_index 0 $dir) $dir"
5600         local out=$($cmd)
5601
5602         [ -z "$out" ] || error "'$cmd' returned directory '$out'"
5603 }
5604 run_test 56i "check 'lfs find -ost UUID' skips directories"
5605
5606 test_56j() {
5607         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5608
5609         setup_56_special $dir $NUMFILES $NUMDIRS
5610
5611         local expected=$((NUMDIRS + 1))
5612         local cmd="$LFS find -type d $dir"
5613         local nums=$($cmd | wc -l)
5614
5615         [ $nums -eq $expected ] ||
5616                 error "'$cmd' wrong: found $nums, expected $expected"
5617 }
5618 run_test 56j "check lfs find -type d"
5619
5620 test_56k() {
5621         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5622
5623         setup_56_special $dir $NUMFILES $NUMDIRS
5624
5625         local expected=$(((NUMDIRS + 1) * NUMFILES))
5626         local cmd="$LFS find -type f $dir"
5627         local nums=$($cmd | wc -l)
5628
5629         [ $nums -eq $expected ] ||
5630                 error "'$cmd' wrong: found $nums, expected $expected"
5631 }
5632 run_test 56k "check lfs find -type f"
5633
5634 test_56l() {
5635         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5636
5637         setup_56_special $dir $NUMFILES $NUMDIRS
5638
5639         local expected=$((NUMDIRS + NUMFILES))
5640         local cmd="$LFS find -type b $dir"
5641         local nums=$($cmd | wc -l)
5642
5643         [ $nums -eq $expected ] ||
5644                 error "'$cmd' wrong: found $nums, expected $expected"
5645 }
5646 run_test 56l "check lfs find -type b"
5647
5648 test_56m() {
5649         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5650
5651         setup_56_special $dir $NUMFILES $NUMDIRS
5652
5653         local expected=$((NUMDIRS + NUMFILES))
5654         local cmd="$LFS find -type c $dir"
5655         local nums=$($cmd | wc -l)
5656         [ $nums -eq $expected ] ||
5657                 error "'$cmd' wrong: found $nums, expected $expected"
5658 }
5659 run_test 56m "check lfs find -type c"
5660
5661 test_56n() {
5662         local dir=$DIR/d$(basetest $testnum)g.$TESTSUITE
5663         setup_56_special $dir $NUMFILES $NUMDIRS
5664
5665         local expected=$((NUMDIRS + NUMFILES))
5666         local cmd="$LFS find -type l $dir"
5667         local nums=$($cmd | wc -l)
5668
5669         [ $nums -eq $expected ] ||
5670                 error "'$cmd' wrong: found $nums, expected $expected"
5671 }
5672 run_test 56n "check lfs find -type l"
5673
5674 test_56o() {
5675         local dir=$DIR/$tdir
5676
5677         setup_56 $dir $NUMFILES $NUMDIRS
5678         utime $dir/file1 > /dev/null || error "utime (1)"
5679         utime $dir/file2 > /dev/null || error "utime (2)"
5680         utime $dir/dir1 > /dev/null || error "utime (3)"
5681         utime $dir/dir2 > /dev/null || error "utime (4)"
5682         utime $dir/dir1/file1 > /dev/null || error "utime (5)"
5683         dd if=/dev/zero count=1 >> $dir/dir1/file1 && sync
5684
5685         local expected=4
5686         local nums=$($LFS find -mtime +0 $dir | wc -l)
5687
5688         [ $nums -eq $expected ] ||
5689                 error "lfs find -mtime +0 $dir: found $nums expect $expected"
5690
5691         expected=12
5692         cmd="$LFS find -mtime 0 $dir"
5693         nums=$($cmd | wc -l)
5694         [ $nums -eq $expected ] ||
5695                 error "'$cmd' wrong: found $nums, expected $expected"
5696 }
5697 run_test 56o "check lfs find -mtime for old files"
5698
5699 test_56ob() {
5700         local dir=$DIR/$tdir
5701         local expected=1
5702         local count=0
5703
5704         # just to make sure there is something that won't be found
5705         test_mkdir $dir
5706         touch $dir/$tfile.now
5707
5708         for age in year week day hour min; do
5709                 count=$((count + 1))
5710
5711                 touch $dir/$tfile-a.$age $dir/$tfile-m.$age
5712                 touch --date="$count $age ago" -a $dir/$tfile-a.$age
5713                 touch --date="$count $age ago" -m $dir/$tfile-m.$age
5714
5715                 local cmd="$LFS find $dir -mtime $count${age:0:1}"
5716                 local nums=$($cmd | wc -l)
5717                 [ $nums -eq $expected ] ||
5718                         error "'$cmd' wrong: found $nums, expected $expected"
5719
5720                 cmd="$LFS find $dir -atime $count${age:0:1}"
5721                 nums=$($cmd | wc -l)
5722                 [ $nums -eq $expected ] ||
5723                         error "'$cmd' wrong: found $nums, expected $expected"
5724         done
5725
5726         sleep 2
5727         cmd="$LFS find $dir -ctime +1s -type f"
5728         nums=$($cmd | wc -l)
5729         (( $nums == $count * 2 + 1)) ||
5730                 error "'$cmd' wrong: found $nums, expected $((expected*2+1))"
5731 }
5732 run_test 56ob "check lfs find -atime -mtime -ctime with units"
5733
5734 test_56p() {
5735         [ $RUNAS_ID -eq $UID ] &&
5736                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5737
5738         local dir=$DIR/$tdir
5739
5740         setup_56 $dir $NUMFILES $NUMDIRS
5741         chown $RUNAS_ID $dir/file* || error "chown $DIR/${tdir}g/file$i failed"
5742
5743         local expected=$NUMFILES
5744         local cmd="$LFS find -uid $RUNAS_ID $dir"
5745         local nums=$($cmd | wc -l)
5746
5747         [ $nums -eq $expected ] ||
5748                 error "'$cmd' wrong: found $nums, expected $expected"
5749
5750         expected=$(((NUMFILES + 1) * NUMDIRS + 1))
5751         cmd="$LFS find ! -uid $RUNAS_ID $dir"
5752         nums=$($cmd | wc -l)
5753         [ $nums -eq $expected ] ||
5754                 error "'$cmd' wrong: found $nums, expected $expected"
5755 }
5756 run_test 56p "check lfs find -uid and ! -uid"
5757
5758 test_56q() {
5759         [ $RUNAS_ID -eq $UID ] &&
5760                 skip_env "RUNAS_ID = UID = $UID -- skipping"
5761
5762         local dir=$DIR/$tdir
5763
5764         setup_56 $dir $NUMFILES $NUMDIRS
5765         chgrp $RUNAS_GID $dir/file* || error "chown $dir/file$i failed"
5766
5767         local expected=$NUMFILES
5768         local cmd="$LFS find -gid $RUNAS_GID $dir"
5769         local nums=$($cmd | wc -l)
5770
5771         [ $nums -eq $expected ] ||
5772                 error "'$cmd' wrong: found $nums, expected $expected"
5773
5774         expected=$(( ($NUMFILES+1) * $NUMDIRS + 1))
5775         cmd="$LFS find ! -gid $RUNAS_GID $dir"
5776         nums=$($cmd | wc -l)
5777         [ $nums -eq $expected ] ||
5778                 error "'$cmd' wrong: found $nums, expected $expected"
5779 }
5780 run_test 56q "check lfs find -gid and ! -gid"
5781
5782 test_56r() {
5783         local dir=$DIR/$tdir
5784
5785         setup_56 $dir $NUMFILES $NUMDIRS
5786
5787         local expected=12
5788         local cmd="$LFS find -size 0 -type f $dir"
5789         local nums=$($cmd | wc -l)
5790
5791         [ $nums -eq $expected ] ||
5792                 error "'$cmd' wrong: found $nums, expected $expected"
5793         expected=0
5794         cmd="$LFS find ! -size 0 -type f $dir"
5795         nums=$($cmd | wc -l)
5796         [ $nums -eq $expected ] ||
5797                 error "'$cmd' wrong: found $nums, expected $expected"
5798         echo "test" > $dir/$tfile
5799         echo "test2" > $dir/$tfile.2 && sync
5800         expected=1
5801         cmd="$LFS find -size 5 -type f $dir"
5802         nums=$($cmd | wc -l)
5803         [ $nums -eq $expected ] ||
5804                 error "'$cmd' wrong: found $nums, expected $expected"
5805         expected=1
5806         cmd="$LFS find -size +5 -type f $dir"
5807         nums=$($cmd | wc -l)
5808         [ $nums -eq $expected ] ||
5809                 error "'$cmd' wrong: found $nums, expected $expected"
5810         expected=2
5811         cmd="$LFS find -size +0 -type f $dir"
5812         nums=$($cmd | wc -l)
5813         [ $nums -eq $expected ] ||
5814                 error "'$cmd' wrong: found $nums, expected $expected"
5815         expected=2
5816         cmd="$LFS find ! -size -5 -type f $dir"
5817         nums=$($cmd | wc -l)
5818         [ $nums -eq $expected ] ||
5819                 error "'$cmd' wrong: found $nums, expected $expected"
5820         expected=12
5821         cmd="$LFS find -size -5 -type f $dir"
5822         nums=$($cmd | wc -l)
5823         [ $nums -eq $expected ] ||
5824                 error "'$cmd' wrong: found $nums, expected $expected"
5825 }
5826 run_test 56r "check lfs find -size works"
5827
5828 test_56s() { # LU-611 #LU-9369
5829         [[ $OSTCOUNT -lt 2 ]] && skip_env "need at least 2 OSTs"
5830
5831         local dir=$DIR/$tdir
5832         local onestripe=$(((NUMDIRS + 1) * NUMFILES))
5833
5834         setup_56 $dir $NUMFILES $NUMDIRS "-c 1"
5835         for i in $(seq $NUMDIRS); do
5836                 $LFS setstripe -c $((OSTCOUNT + 1)) $dir/dir$i/$tfile
5837         done
5838
5839         local expected=$NUMDIRS
5840         local cmd="$LFS find -c $OSTCOUNT $dir"
5841         local nums=$($cmd | wc -l)
5842
5843         [ $nums -eq $expected ] || {
5844                 $LFS getstripe -R $dir
5845                 error "'$cmd' wrong: found $nums, expected $expected"
5846         }
5847
5848         expected=$((NUMDIRS + onestripe))
5849         cmd="$LFS find -stripe-count +0 -type f $dir"
5850         nums=$($cmd | wc -l)
5851         [ $nums -eq $expected ] || {
5852                 $LFS getstripe -R $dir
5853                 error "'$cmd' wrong: found $nums, expected $expected"
5854         }
5855
5856         expected=$onestripe
5857         cmd="$LFS find -stripe-count 1 -type f $dir"
5858         nums=$($cmd | wc -l)
5859         [ $nums -eq $expected ] || {
5860                 $LFS getstripe -R $dir
5861                 error "'$cmd' wrong: found $nums, expected $expected"
5862         }
5863
5864         cmd="$LFS find -stripe-count -2 -type f $dir"
5865         nums=$($cmd | wc -l)
5866         [ $nums -eq $expected ] || {
5867                 $LFS getstripe -R $dir
5868                 error "'$cmd' wrong: found $nums, expected $expected"
5869         }
5870
5871         expected=0
5872         cmd="$LFS find -stripe-count $((OSTCOUNT + 1)) -type f $dir"
5873         nums=$($cmd | wc -l)
5874         [ $nums -eq $expected ] || {
5875                 $LFS getstripe -R $dir
5876                 error "'$cmd' wrong: found $nums, expected $expected"
5877         }
5878 }
5879 run_test 56s "check lfs find -stripe-count works"
5880
5881 test_56t() { # LU-611 #LU-9369
5882         local dir=$DIR/$tdir
5883
5884         setup_56 $dir 0 $NUMDIRS
5885         for i in $(seq $NUMDIRS); do
5886                 $LFS setstripe -S 8M $dir/dir$i/$tfile
5887         done
5888
5889         local expected=$NUMDIRS
5890         local cmd="$LFS find -S 8M $dir"
5891         local nums=$($cmd | wc -l)
5892
5893         [ $nums -eq $expected ] || {
5894                 $LFS getstripe -R $dir
5895                 error "'$cmd' wrong: found $nums, expected $expected"
5896         }
5897         rm -rf $dir
5898
5899         setup_56 $dir $NUMFILES $NUMDIRS "--stripe-size 512k"
5900
5901         $LFS setstripe -S 256k $dir/$tfile.{0,1,2,3}
5902
5903         expected=$(((NUMDIRS + 1) * NUMFILES))
5904         cmd="$LFS find -stripe-size 512k -type f $dir"
5905         nums=$($cmd | wc -l)
5906         [ $nums -eq $expected ] ||
5907                 error "'$cmd' wrong: found $nums, expected $expected"
5908
5909         cmd="$LFS find -stripe-size +320k -type f $dir"
5910         nums=$($cmd | wc -l)
5911         [ $nums -eq $expected ] ||
5912                 error "'$cmd' wrong: found $nums, expected $expected"
5913
5914         expected=$(((NUMDIRS + 1) * NUMFILES + 4))
5915         cmd="$LFS find -stripe-size +200k -type f $dir"
5916         nums=$($cmd | wc -l)
5917         [ $nums -eq $expected ] ||
5918                 error "'$cmd' wrong: found $nums, expected $expected"
5919
5920         cmd="$LFS find -stripe-size -640k -type f $dir"
5921         nums=$($cmd | wc -l)
5922         [ $nums -eq $expected ] ||
5923                 error "'$cmd' wrong: found $nums, expected $expected"
5924
5925         expected=4
5926         cmd="$LFS find -stripe-size 256k -type f $dir"
5927         nums=$($cmd | wc -l)
5928         [ $nums -eq $expected ] ||
5929                 error "'$cmd' wrong: found $nums, expected $expected"
5930
5931         cmd="$LFS find -stripe-size -320k -type f $dir"
5932         nums=$($cmd | wc -l)
5933         [ $nums -eq $expected ] ||
5934                 error "'$cmd' wrong: found $nums, expected $expected"
5935
5936         expected=0
5937         cmd="$LFS find -stripe-size 1024k -type f $dir"
5938         nums=$($cmd | wc -l)
5939         [ $nums -eq $expected ] ||
5940                 error "'$cmd' wrong: found $nums, expected $expected"
5941 }
5942 run_test 56t "check lfs find -stripe-size works"
5943
5944 test_56u() { # LU-611
5945         local dir=$DIR/$tdir
5946
5947         setup_56 $dir $NUMFILES $NUMDIRS "-i 0 -c 1"
5948
5949         if [[ $OSTCOUNT -gt 1 ]]; then
5950                 $LFS setstripe -i 1 -c 1 $dir/$tfile.{0,1,2,3}
5951                 onestripe=4
5952         else
5953                 onestripe=0
5954         fi
5955
5956         local expected=$(((NUMDIRS + 1) * NUMFILES))
5957         local cmd="$LFS find -stripe-index 0 -type f $dir"
5958         local nums=$($cmd | wc -l)
5959
5960         [ $nums -eq $expected ] ||
5961                 error "'$cmd' wrong: found $nums, expected $expected"
5962
5963         expected=$onestripe
5964         cmd="$LFS find -stripe-index 1 -type f $dir"
5965         nums=$($cmd | wc -l)
5966         [ $nums -eq $expected ] ||
5967                 error "'$cmd' wrong: found $nums, expected $expected"
5968
5969         cmd="$LFS find ! -stripe-index 0 -type f $dir"
5970         nums=$($cmd | wc -l)
5971         [ $nums -eq $expected ] ||
5972                 error "'$cmd' wrong: found $nums, expected $expected"
5973
5974         expected=0
5975         # This should produce an error and not return any files
5976         cmd="$LFS find -stripe-index $OSTCOUNT -type f $dir"
5977         nums=$($cmd 2>/dev/null | wc -l)
5978         [ $nums -eq $expected ] ||
5979                 error "'$cmd' wrong: found $nums, expected $expected"
5980
5981         if [[ $OSTCOUNT -gt 1 ]]; then
5982                 expected=$(((NUMDIRS + 1) * NUMFILES + onestripe))
5983                 cmd="$LFS find -stripe-index 0,1 -type f $dir"
5984                 nums=$($cmd | wc -l)
5985                 [ $nums -eq $expected ] ||
5986                         error "'$cmd' wrong: found $nums, expected $expected"
5987         fi
5988 }
5989 run_test 56u "check lfs find -stripe-index works"
5990
5991 test_56v() {
5992         local mdt_idx=0
5993         local dir=$DIR/$tdir
5994
5995         setup_56 $dir $NUMFILES $NUMDIRS
5996
5997         UUID=$(mdtuuid_from_index $mdt_idx $dir)
5998         [ -z "$UUID" ] && error "mdtuuid_from_index cannot find MDT $mdt_idx"
5999
6000         for file in $($LFS find -m $UUID $dir); do
6001                 file_midx=$($LFS getstripe -m $file)
6002                 [ $file_midx -eq $mdt_idx ] ||
6003                         error "lfs find -m $UUID != getstripe -m $file_midx"
6004         done
6005 }
6006 run_test 56v "check 'lfs find -m match with lfs getstripe -m'"
6007
6008 test_56w() {
6009         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6010         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6011
6012         local dir=$DIR/$tdir
6013
6014         setup_56 $dir $NUMFILES $NUMDIRS "-c $OSTCOUNT" "-c1"
6015
6016         local stripe_size=$($LFS getstripe -S -d $dir) ||
6017                 error "$LFS getstripe -S -d $dir failed"
6018         stripe_size=${stripe_size%% *}
6019
6020         local file_size=$((stripe_size * OSTCOUNT))
6021         local file_num=$((NUMDIRS * NUMFILES + NUMFILES))
6022         local required_space=$((file_num * file_size))
6023         local free_space=$($LCTL get_param -n lov.$FSNAME-clilov-*.kbytesavail |
6024                            head -n1)
6025         [[ $free_space -le $((required_space / 1024)) ]] &&
6026                 skip_env "need $required_space, have $free_space kbytes"
6027
6028         local dd_bs=65536
6029         local dd_count=$((file_size / dd_bs))
6030
6031         # write data into the files
6032         local i
6033         local j
6034         local file
6035
6036         for i in $(seq $NUMFILES); do
6037                 file=$dir/file$i
6038                 yes | dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6039                         error "write data into $file failed"
6040         done
6041         for i in $(seq $NUMDIRS); do
6042                 for j in $(seq $NUMFILES); do
6043                         file=$dir/dir$i/file$j
6044                         yes|dd bs=$dd_bs count=$dd_count of=$file &>/dev/null ||
6045                                 error "write data into $file failed"
6046                 done
6047         done
6048
6049         # $LFS_MIGRATE will fail if hard link migration is unsupported
6050         if [[ $(lustre_version_code mds1) -gt $(version_code 2.5.55) ]]; then
6051                 createmany -l$dir/dir1/file1 $dir/dir1/link 200 ||
6052                         error "creating links to $dir/dir1/file1 failed"
6053         fi
6054
6055         local expected=-1
6056
6057         [[ $OSTCOUNT -gt 1 ]] && expected=$((OSTCOUNT - 1))
6058
6059         # lfs_migrate file
6060         local cmd="$LFS_MIGRATE -y -c $expected $dir/file1"
6061
6062         echo "$cmd"
6063         eval $cmd || error "$cmd failed"
6064
6065         check_stripe_count $dir/file1 $expected
6066
6067         if [ $MDS1_VERSION -ge $(version_code 2.6.90) ];
6068         then
6069                 # lfs_migrate file onto OST 0 if it is on OST 1, or onto
6070                 # OST 1 if it is on OST 0. This file is small enough to
6071                 # be on only one stripe.
6072                 file=$dir/migr_1_ost
6073                 dd bs=$dd_bs count=1 if=/dev/urandom of=$file >/dev/null 2>&1 ||
6074                         error "write data into $file failed"
6075                 local obdidx=$($LFS getstripe -i $file)
6076                 local oldmd5=$(md5sum $file)
6077                 local newobdidx=0
6078
6079                 [[ $obdidx -eq 0 ]] && newobdidx=1
6080                 cmd="$LFS migrate -i $newobdidx $file"
6081                 echo $cmd
6082                 eval $cmd || error "$cmd failed"
6083
6084                 local realobdix=$($LFS getstripe -i $file)
6085                 local newmd5=$(md5sum $file)
6086
6087                 [[ $newobdidx -ne $realobdix ]] &&
6088                         error "new OST is different (was=$obdidx, "\
6089                               "wanted=$newobdidx, got=$realobdix)"
6090                 [[ "$oldmd5" != "$newmd5" ]] &&
6091                         error "md5sum differ: $oldmd5, $newmd5"
6092         fi
6093
6094         # lfs_migrate dir
6095         cmd="$LFS_MIGRATE -y -c $expected $dir/dir1"
6096         echo "$cmd"
6097         eval $cmd || error "$cmd failed"
6098
6099         for j in $(seq $NUMFILES); do
6100                 check_stripe_count $dir/dir1/file$j $expected
6101         done
6102
6103         # lfs_migrate works with lfs find
6104         cmd="$LFS find -stripe_count $OSTCOUNT -type f $dir |
6105              $LFS_MIGRATE -y -c $expected"
6106         echo "$cmd"
6107         eval $cmd || error "$cmd failed"
6108
6109         for i in $(seq 2 $NUMFILES); do
6110                 check_stripe_count $dir/file$i $expected
6111         done
6112         for i in $(seq 2 $NUMDIRS); do
6113                 for j in $(seq $NUMFILES); do
6114                 check_stripe_count $dir/dir$i/file$j $expected
6115                 done
6116         done
6117 }
6118 run_test 56w "check lfs_migrate -c stripe_count works"
6119
6120 test_56wb() {
6121         local file1=$DIR/$tdir/file1
6122         local create_pool=false
6123         local initial_pool=$($LFS getstripe -p $DIR)
6124         local pool_list=()
6125         local pool=""
6126
6127         echo -n "Creating test dir..."
6128         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6129         echo "done."
6130
6131         echo -n "Creating test file..."
6132         touch $file1 || error "cannot create file"
6133         echo "done."
6134
6135         echo -n "Detecting existing pools..."
6136         pool_list=($($LFS pool_list $FSNAME | grep "$FSNAME\." | cut -d. -f2))
6137
6138         if [ ${#pool_list[@]} -gt 0 ]; then
6139                 echo "${pool_list[@]}"
6140                 for thispool in "${pool_list[@]}"; do
6141                         if [[ -z "$initial_pool" ||
6142                               "$initial_pool" != "$thispool" ]]; then
6143                                 pool="$thispool"
6144                                 echo "Using existing pool '$pool'"
6145                                 break
6146                         fi
6147                 done
6148         else
6149                 echo "none detected."
6150         fi
6151         if [ -z "$pool" ]; then
6152                 pool=${POOL:-testpool}
6153                 [ "$initial_pool" = "$pool" ] && pool="testpool2"
6154                 echo -n "Creating pool '$pool'..."
6155                 create_pool=true
6156                 pool_add $pool &> /dev/null ||
6157                         error "pool_add failed"
6158                 echo "done."
6159
6160                 echo -n "Adding target to pool..."
6161                 pool_add_targets $pool 0 0 1 &> /dev/null ||
6162                         error "pool_add_targets failed"
6163                 echo "done."
6164         fi
6165
6166         echo -n "Setting pool using -p option..."
6167         $LFS_MIGRATE -y -q --no-rsync -p $pool $file1 &> /dev/null ||
6168                 error "migrate failed rc = $?"
6169         echo "done."
6170
6171         echo -n "Verifying test file is in pool after migrating..."
6172         [ "$($LFS getstripe -p $file1)" = $pool ] ||
6173                 error "file was not migrated to pool $pool"
6174         echo "done."
6175
6176         echo -n "Removing test file from pool '$pool'..."
6177         $LFS migrate $file1 &> /dev/null ||
6178                 error "cannot remove from pool"
6179         [ "$($LFS getstripe -p $file1)" ] &&
6180                 error "pool still set"
6181         echo "done."
6182
6183         echo -n "Setting pool using --pool option..."
6184         $LFS_MIGRATE -y -q --no-rsync --pool $pool $file1 &> /dev/null ||
6185                 error "migrate failed rc = $?"
6186         echo "done."
6187
6188         # Clean up
6189         rm -f $file1
6190         if $create_pool; then
6191                 destroy_test_pools 2> /dev/null ||
6192                         error "destroy test pools failed"
6193         fi
6194 }
6195 run_test 56wb "check lfs_migrate pool support"
6196
6197 test_56wc() {
6198         local file1="$DIR/$tdir/file1"
6199
6200         echo -n "Creating test dir..."
6201         test_mkdir $DIR/$tdir &> /dev/null || error "cannot create dir"
6202         local def_stripe_size=$($LFS getstripe -S $DIR/$tdir 2>/dev/null)
6203         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6204                 error "cannot set stripe"
6205         echo "done"
6206
6207         echo -n "Setting initial stripe for test file..."
6208         $LFS setstripe -S 512K -c 1 "$file1" &> /dev/null ||
6209                 error "cannot set stripe"
6210         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6211                 error "stripe size not set"
6212         echo "done."
6213
6214         # File currently set to -S 512K -c 1
6215
6216         # Ensure -c and -S options are rejected when -R is set
6217         echo -n "Verifying incompatible options are detected..."
6218         $LFS_MIGRATE -y -R -c 1 "$file1" &> /dev/null &&
6219                 error "incompatible -c and -R options not detected"
6220         $LFS_MIGRATE -y -R -S 1M "$file1" &> /dev/null &&
6221                 error "incompatible -S and -R options not detected"
6222         echo "done."
6223
6224         # Ensure unrecognized options are passed through to 'lfs migrate'
6225         echo -n "Verifying -S option is passed through to lfs migrate..."
6226         $LFS_MIGRATE -y -S 1M "$file1" &> /dev/null ||
6227                 error "migration failed"
6228         [ $($LFS getstripe -S "$file1") -eq 1048576 ] ||
6229                 error "file was not restriped"
6230         echo "done."
6231
6232         # File currently set to -S 1M -c 1
6233
6234         # Ensure long options are supported
6235         echo -n "Verifying long options supported..."
6236         $LFS_MIGRATE -y --non-block "$file1" &> /dev/null ||
6237                 error "long option without argument not supported"
6238         $LFS_MIGRATE -y --stripe-size 512K "$file1" &> /dev/null ||
6239                 error "long option with argument not supported"
6240         [ $($LFS getstripe -S "$file1") -eq 524288 ] ||
6241                 error "file not restriped with --stripe-size option"
6242         echo "done."
6243
6244         # File currently set to -S 512K -c 1
6245
6246         if [ "$OSTCOUNT" -gt 1 ]; then
6247                 echo -n "Verifying explicit stripe count can be set..."
6248                 $LFS_MIGRATE -y -c 2 "$file1" &> /dev/null ||
6249                         error "migrate failed"
6250                 [ $($LFS getstripe -c "$file1") -eq 2 ] ||
6251                         error "file not restriped to explicit count"
6252                 echo "done."
6253         fi
6254
6255         # File currently set to -S 512K -c 1 or -S 512K -c 2
6256
6257         # Ensure parent striping is used if -R is set, and no stripe
6258         # count or size is specified
6259         echo -n "Setting stripe for parent directory..."
6260         $LFS setstripe -S 1M -c 1 "$DIR/$tdir" &> /dev/null ||
6261                 error "cannot set stripe"
6262         echo "done."
6263
6264         echo -n "Verifying restripe option uses parent stripe settings..."
6265         $LFS_MIGRATE -y -R "$file1" &> /dev/null ||
6266                 error "migrate failed"
6267         [ $($LFS getstripe -S "$file1") -eq $def_stripe_size ] ||
6268                 error "file not restriped to parent settings"
6269         [ $($LFS getstripe -c "$file1") -eq 1 ] ||
6270                 error "file not restriped to parent settings"
6271         echo "done."
6272
6273         # File currently set to -S 1M -c 1
6274
6275         # Ensure striping is preserved if -R is not set, and no stripe
6276         # count or size is specified
6277         echo -n "Verifying striping size preserved when not specified..."
6278         local orig_stripe_size=$($LFS getstripe -S "$file1" 2>/dev/null)
6279         $LFS setstripe -S 2M -c 1 "$DIR/$tdir" &> /dev/null ||
6280                 error "cannot set stripe on parent directory"
6281         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6282                 error "migrate failed"
6283         [ $($LFS getstripe -S "$file1") -eq $orig_stripe_size ] ||
6284                 error "file was restriped"
6285         echo "done."
6286
6287         # Ensure file name properly detected when final option has no argument
6288         echo -n "Verifying file name properly detected..."
6289         $LFS_MIGRATE -y "$file1" &> /dev/null ||
6290                 error "file name interpreted as option argument"
6291         echo "done."
6292
6293         # Clean up
6294         rm -f "$file1"
6295 }
6296 run_test 56wc "check unrecognized options for lfs_migrate are passed through"
6297
6298 test_56wd() {
6299         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6300
6301         local file1=$DIR/$tdir/file1
6302
6303         echo -n "Creating test dir..."
6304         test_mkdir $DIR/$tdir || error "cannot create dir"
6305         echo "done."
6306
6307         echo -n "Creating test file..."
6308         touch $file1
6309         echo "done."
6310
6311         # Ensure 'lfs migrate' will fail by using a non-existent option,
6312         # and make sure rsync is not called to recover
6313         echo -n "Make sure --no-rsync option works..."
6314         $LFS_MIGRATE -y --no-rsync --invalid-opt $file1 2>&1 |
6315                 grep -q 'refusing to fall back to rsync' ||
6316                 error "rsync was called with --no-rsync set"
6317         echo "done."
6318
6319         # Ensure rsync is called without trying 'lfs migrate' first
6320         echo -n "Make sure --rsync option works..."
6321         $LFS_MIGRATE -y --rsync --invalid-opt $file1 2>&1 |
6322                 grep -q 'falling back to rsync' &&
6323                 error "lfs migrate was called with --rsync set"
6324         echo "done."
6325
6326         echo -n "Make sure --rsync and --no-rsync options are exclusive..."
6327         $LFS_MIGRATE -y --rsync --no-rsync $file1 2>&1 |
6328                 grep -q 'at the same time' ||
6329                 error "--rsync and --no-rsync accepted concurrently"
6330         echo "done."
6331
6332         # Clean up
6333         rm -f $file1
6334 }
6335 run_test 56wd "check lfs_migrate --rsync and --no-rsync work"
6336
6337 test_56x() {
6338         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6339         check_swap_layouts_support
6340
6341         local dir=$DIR/$tdir
6342         local ref1=/etc/passwd
6343         local file1=$dir/file1
6344
6345         test_mkdir $dir || error "creating dir $dir"
6346         $LFS setstripe -c 2 $file1
6347         cp $ref1 $file1
6348         $LFS migrate -c 1 $file1 || error "migrate failed rc = $?"
6349         stripe=$($LFS getstripe -c $file1)
6350         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6351         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6352
6353         # clean up
6354         rm -f $file1
6355 }
6356 run_test 56x "lfs migration support"
6357
6358 test_56xa() {
6359         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6360         check_swap_layouts_support
6361
6362         local dir=$DIR/$tdir/$testnum
6363
6364         test_mkdir -p $dir
6365
6366         local ref1=/etc/passwd
6367         local file1=$dir/file1
6368
6369         $LFS setstripe -c 2 $file1
6370         cp $ref1 $file1
6371         $LFS migrate --block -c 1 $file1 || error "migrate failed rc = $?"
6372
6373         local stripe=$($LFS getstripe -c $file1)
6374
6375         [[ $stripe == 1 ]] || error "stripe of $file1 is $stripe != 1"
6376         cmp $file1 $ref1 || error "content mismatch $file1 differs from $ref1"
6377
6378         # clean up
6379         rm -f $file1
6380 }
6381 run_test 56xa "lfs migration --block support"
6382
6383 check_migrate_links() {
6384         local dir="$1"
6385         local file1="$dir/file1"
6386         local begin="$2"
6387         local count="$3"
6388         local total_count=$(($begin + $count - 1))
6389         local symlink_count=10
6390         local uniq_count=10
6391
6392         if [ ! -f "$file1" ]; then
6393                 echo -n "creating initial file..."
6394                 $LFS setstripe -c 1 -S "512k" "$file1" ||
6395                         error "cannot setstripe initial file"
6396                 echo "done"
6397
6398                 echo -n "creating symlinks..."
6399                 for s in $(seq 1 $symlink_count); do
6400                         ln -s "$file1" "$dir/slink$s" ||
6401                                 error "cannot create symlinks"
6402                 done
6403                 echo "done"
6404
6405                 echo -n "creating nonlinked files..."
6406                 createmany -o "$dir/uniq" 1 10 &> /dev/null ||
6407                         error "cannot create nonlinked files"
6408                 echo "done"
6409         fi
6410
6411         # create hard links
6412         if [ ! -f "$dir/file$total_count" ]; then
6413                 echo -n "creating hard links $begin:$total_count..."
6414                 createmany -l"$file1" "$dir/file" "$begin" "$count" &>  \
6415                         /dev/null || error "cannot create hard links"
6416                 echo "done"
6417         fi
6418
6419         echo -n "checking number of hard links listed in xattrs..."
6420         local fid=$($LFS getstripe -F "$file1")
6421         local paths=($($LFS fid2path "$MOUNT" "$fid" 2> /dev/null))
6422
6423         echo "${#paths[*]}"
6424         if [ ${#paths[*]} -lt $total_count -a "$begin" -eq 2  ]; then
6425                         skip "hard link list has unexpected size, skipping test"
6426         fi
6427         if [ ${#paths[*]} -ge $total_count -a "$begin" -ne 2  ]; then
6428                         error "link names should exceed xattrs size"
6429         fi
6430
6431         echo -n "migrating files..."
6432         local migrate_out=$($LFS_MIGRATE -y -S '1m' $dir)
6433         local rc=$?
6434         [ $rc -eq 0 ] || error "migrate failed rc = $rc"
6435         echo "done"
6436
6437         # make sure all links have been properly migrated
6438         echo -n "verifying files..."
6439         fid=$($LFS getstripe -F "$file1") ||
6440                 error "cannot get fid for file $file1"
6441         for i in $(seq 2 $total_count); do
6442                 local fid2=$($LFS getstripe -F $dir/file$i)
6443
6444                 [ "$fid2" == "$fid" ] ||
6445                         error "migrated hard link has mismatched FID"
6446         done
6447
6448         # make sure hard links were properly detected, and migration was
6449         # performed only once for the entire link set; nonlinked files should
6450         # also be migrated
6451         local actual=$(grep -c 'done' <<< "$migrate_out")
6452         local expected=$(($uniq_count + 1))
6453
6454         [ "$actual" -eq  "$expected" ] ||
6455                 error "hard links individually migrated ($actual != $expected)"
6456
6457         # make sure the correct number of hard links are present
6458         local hardlinks=$(stat -c '%h' "$file1")
6459
6460         [ $hardlinks -eq $total_count ] ||
6461                 error "num hard links $hardlinks != $total_count"
6462         echo "done"
6463
6464         return 0
6465 }
6466
6467 test_56xb() {
6468         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
6469                 skip "Need MDS version at least 2.10.55"
6470
6471         local dir="$DIR/$tdir"
6472
6473         test_mkdir "$dir" || error "cannot create dir $dir"
6474
6475         echo "testing lfs migrate mode when all links fit within xattrs"
6476         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 2 99
6477
6478         echo "testing rsync mode when all links fit within xattrs"
6479         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 2 99
6480
6481         echo "testing lfs migrate mode when all links do not fit within xattrs"
6482         LFS_MIGRATE_RSYNC_MODE=false check_migrate_links "$dir" 101 100
6483
6484         echo "testing rsync mode when all links do not fit within xattrs"
6485         LFS_MIGRATE_RSYNC_MODE=true check_migrate_links "$dir" 101 100
6486
6487
6488         # clean up
6489         rm -rf $dir
6490 }
6491 run_test 56xb "lfs migration hard link support"
6492
6493 test_56xc() {
6494         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
6495
6496         local dir="$DIR/$tdir"
6497
6498         test_mkdir "$dir" || error "cannot create dir $dir"
6499
6500         # Test 1: ensure file < 1 GB is always migrated with 1 stripe
6501         echo -n "Setting initial stripe for 20MB test file..."
6502         $LFS setstripe -c 2 -i 0 "$dir/20mb" ||
6503                 error "cannot setstripe 20MB file"
6504         echo "done"
6505         echo -n "Sizing 20MB test file..."
6506         truncate "$dir/20mb" 20971520 || error "cannot create 20MB test file"
6507         echo "done"
6508         echo -n "Verifying small file autostripe count is 1..."
6509         $LFS_MIGRATE -y -A -C 1 "$dir/20mb" ||
6510                 error "cannot migrate 20MB file"
6511         local stripe_count=$($LFS getstripe -c "$dir/20mb") ||
6512                 error "cannot get stripe for $dir/20mb"
6513         [ $stripe_count -eq 1 ] ||
6514                 error "unexpected stripe count $stripe_count for 20MB file"
6515         rm -f "$dir/20mb"
6516         echo "done"
6517
6518         # Test 2: File is small enough to fit within the available space on
6519         # sqrt(size_in_gb) + 1 OSTs but is larger than 1GB.  The file must
6520         # have at least an additional 1KB for each desired stripe for test 3
6521         echo -n "Setting stripe for 1GB test file..."
6522         $LFS setstripe -c 1 -i 0 "$dir/1gb" || error "cannot setstripe 1GB file"
6523         echo "done"
6524         echo -n "Sizing 1GB test file..."
6525         # File size is 1GB + 3KB
6526         truncate "$dir/1gb" 1073744896 || error "cannot create 1GB test file"
6527         echo "done"
6528
6529         # need at least 512MB per OST for 1GB file to fit in 2 stripes
6530         local avail=$($LCTL get_param -n llite.$FSNAME*.kbytesavail)
6531         if (( avail > 524288 * OSTCOUNT )); then
6532                 echo -n "Migrating 1GB file..."
6533                 $LFS_MIGRATE -y -A -C 1 "$dir/1gb" ||
6534                         error "cannot migrate 1GB file"
6535                 echo "done"
6536                 echo -n "Verifying autostripe count is sqrt(n) + 1..."
6537                 stripe_count=$($LFS getstripe -c "$dir/1gb") ||
6538                         error "cannot getstripe for 1GB file"
6539                 [ $stripe_count -eq 2 ] ||
6540                         error "unexpected stripe count $stripe_count != 2"
6541                 echo "done"
6542         fi
6543
6544         # Test 3: File is too large to fit within the available space on
6545         # sqrt(n) + 1 OSTs.  Simulate limited available space with -X
6546         if [ $OSTCOUNT -ge 3 ]; then
6547                 # The required available space is calculated as
6548                 # file size (1GB + 3KB) / OST count (3).
6549                 local kb_per_ost=349526
6550
6551                 echo -n "Migrating 1GB file with limit..."
6552                 $LFS_MIGRATE -y -A -C 1 -X $kb_per_ost "$dir/1gb" ||
6553                         error "cannot migrate 1GB file with limit"
6554                 echo "done"
6555
6556                 stripe_count=$($LFS getstripe -c "$dir/1gb")
6557                 echo -n "Verifying 1GB autostripe count with limited space..."
6558                 [ "$stripe_count" -a $stripe_count -ge 3 ] ||
6559                         error "unexpected stripe count $stripe_count (min 3)"
6560                 echo "done"
6561         fi
6562
6563         # clean up
6564         rm -rf $dir
6565 }
6566 run_test 56xc "lfs migration autostripe"
6567
6568 test_56y() {
6569         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
6570                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
6571
6572         local res=""
6573         local dir=$DIR/$tdir
6574         local f1=$dir/file1
6575         local f2=$dir/file2
6576
6577         test_mkdir -p $dir || error "creating dir $dir"
6578         touch $f1 || error "creating std file $f1"
6579         $MULTIOP $f2 H2c || error "creating released file $f2"
6580
6581         # a directory can be raid0, so ask only for files
6582         res=$($LFS find $dir -L raid0 -type f | wc -l)
6583         [[ $res == 2 ]] || error "search raid0: found $res files != 2"
6584
6585         res=$($LFS find $dir \! -L raid0 -type f | wc -l)
6586         [[ $res == 0 ]] || error "search !raid0: found $res files != 0"
6587
6588         # only files can be released, so no need to force file search
6589         res=$($LFS find $dir -L released)
6590         [[ $res == $f2 ]] || error "search released: found $res != $f2"
6591
6592         res=$($LFS find $dir -type f \! -L released)
6593         [[ $res == $f1 ]] || error "search !released: found $res != $f1"
6594 }
6595 run_test 56y "lfs find -L raid0|released"
6596
6597 test_56z() { # LU-4824
6598         # This checks to make sure 'lfs find' continues after errors
6599         # There are two classes of errors that should be caught:
6600         # - If multiple paths are provided, all should be searched even if one
6601         #   errors out
6602         # - If errors are encountered during the search, it should not terminate
6603         #   early
6604         local dir=$DIR/$tdir
6605         local i
6606
6607         test_mkdir $dir
6608         for i in d{0..9}; do
6609                 test_mkdir $dir/$i
6610                 touch $dir/$i/$tfile
6611         done
6612         $LFS find $DIR/non_existent_dir $dir &&
6613                 error "$LFS find did not return an error"
6614         # Make a directory unsearchable. This should NOT be the last entry in
6615         # directory order.  Arbitrarily pick the 6th entry
6616         chmod 700 $($LFS find $dir -type d | sed '6!d')
6617
6618         $RUNAS $LFS find $DIR/non_existent $dir
6619         local count=$($RUNAS $LFS find $DIR/non_existent $dir | wc -l)
6620
6621         # The user should be able to see 10 directories and 9 files
6622         (( count == 19 )) ||
6623                 error "$LFS find found $count != 19 entries after error"
6624 }
6625 run_test 56z "lfs find should continue after an error"
6626
6627 test_56aa() { # LU-5937
6628         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
6629
6630         local dir=$DIR/$tdir
6631
6632         mkdir $dir
6633         $LFS setdirstripe -c$MDSCOUNT $dir/striped_dir
6634
6635         createmany -o $dir/striped_dir/${tfile}- 1024
6636         local dirs=$($LFS find --size +8k $dir/)
6637
6638         [ -n "$dirs" ] || error "lfs find --size wrong under striped dir"
6639 }
6640 run_test 56aa "lfs find --size under striped dir"
6641
6642 test_56ab() { # LU-10705
6643         test_mkdir $DIR/$tdir
6644         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=8k count=1 seek=2k
6645         dd if=/dev/zero of=$DIR/$tdir/$tfile.2 bs=4k count=1 seek=4k
6646         dd if=/dev/zero of=$DIR/$tdir/$tfile.3 bs=1M count=2 seek=16
6647         # Flush writes to ensure valid blocks.  Need to be more thorough for
6648         # ZFS, since blocks are not allocated/returned to client immediately.
6649         sync_all_data
6650         wait_zfs_commit ost1 2
6651         cancel_lru_locks osc
6652         ls -ls $DIR/$tdir
6653
6654         local files=$($LFS find --size +16M $DIR/$tdir | wc -l)
6655
6656         [[ $files == 3 ]] || error ">16M size files $files isn't 3 as expected"
6657
6658         files=$($LFS find --blocks +1M $DIR/$tdir | wc -l)
6659         [[ $files == 1 ]] || error ">1M blocks files $files isn't 1 as expected"
6660
6661         rm -f $DIR/$tdir/$tfile.[123]
6662 }
6663 run_test 56ab "lfs find --blocks"
6664
6665 test_56ba() {
6666         [ $MDS1_VERSION -lt $(version_code 2.10.50) ] &&
6667                 skip "Need MDS version at least 2.10.50"
6668
6669         # Create composite files with one component
6670         local dir=$DIR/$tdir
6671
6672         setup_56 $dir/1Mfiles 5 1 "-S 1M --component-end 1M"
6673         # Create composite files with three components
6674         setup_56 $dir/2Mfiles 5 2 "-E 2M -S 1M -E 4M -E 6M"
6675         # Create non-composite files
6676         createmany -o $dir/${tfile}- 10
6677
6678         local nfiles=$($LFS find --component-end 1M --type f $dir | wc -l)
6679
6680         [[ $nfiles == 10 ]] ||
6681                 error "lfs find -E 1M found $nfiles != 10 files"
6682
6683         nfiles=$($LFS find ! -E 1M --type f $dir | wc -l)
6684         [[ $nfiles == 25 ]] ||
6685                 error "lfs find ! -E 1M found $nfiles != 25 files"
6686
6687         # All files have a component that starts at 0
6688         nfiles=$($LFS find --component-start 0 --type f $dir | wc -l)
6689         [[ $nfiles == 35 ]] ||
6690                 error "lfs find --component-start 0 - $nfiles != 35 files"
6691
6692         nfiles=$($LFS find --component-start 2M --type f $dir | wc -l)
6693         [[ $nfiles == 15 ]] ||
6694                 error "lfs find --component-start 2M - $nfiles != 15 files"
6695
6696         # All files created here have a componenet that does not starts at 2M
6697         nfiles=$($LFS find ! --component-start 2M --type f $dir | wc -l)
6698         [[ $nfiles == 35 ]] ||
6699                 error "lfs find ! --component-start 2M - $nfiles != 35 files"
6700
6701         # Find files with a specified number of components
6702         local nfiles=$($LFS find --component-count 3 --type f $dir | wc -l)
6703         [[ $nfiles == 15 ]] ||
6704                 error "lfs find --component-count 3 - $nfiles != 15 files"
6705
6706         # Remember non-composite files have a component count of zero
6707         local nfiles=$($LFS find --component-count 0 --type f $dir | wc -l)
6708         [[ $nfiles == 10 ]] ||
6709                 error "lfs find --component-count 0 - $nfiles != 10 files"
6710
6711         nfiles=$($LFS find ! --component-count 3 --type f $dir | wc -l)
6712         [[ $nfiles == 20 ]] ||
6713                 error "lfs find ! --component-count 3 - $nfiles != 20 files"
6714
6715         # All files have a flag called "init"
6716         local nfiles=$($LFS find --component-flags init --type f $dir | wc -l)
6717         [[ $nfiles == 35 ]] ||
6718                 error "lfs find --component-flags init - $nfiles != 35 files"
6719
6720         # Multi-component files will have a component not initialized
6721         local nfiles=$($LFS find ! --component-flags init --type f $dir | wc -l)
6722         [[ $nfiles == 15 ]] ||
6723                 error "lfs find !--component-flags init - $nfiles != 15 files"
6724
6725         rm -rf $dir
6726
6727 }
6728 run_test 56ba "test lfs find --component-end, -start, -count, and -flags"
6729
6730 test_56ca() {
6731         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
6732                 skip "Need MDS version at least 2.10.57"
6733
6734         local td=$DIR/$tdir
6735         local tf=$td/$tfile
6736         local dir
6737         local nfiles
6738         local cmd
6739         local i
6740         local j
6741
6742         # create mirrored directories and mirrored files
6743         mkdir $td || error "mkdir $td failed"
6744         $LFS mirror create -N3 $td || error "create mirrored dir $td failed"
6745         createmany -o $tf- 10 || error "create $tf- failed"
6746
6747         for i in $(seq 2); do
6748                 dir=$td/dir$i
6749                 mkdir $dir || error "mkdir $dir failed"
6750                 $LFS mirror create -N$((3 + i)) $dir ||
6751                         error "create mirrored dir $dir failed"
6752                 createmany -o $dir/$tfile- 10 ||
6753                         error "create $dir/$tfile- failed"
6754         done
6755
6756         # change the states of some mirrored files
6757         echo foo > $tf-6
6758         for i in $(seq 2); do
6759                 dir=$td/dir$i
6760                 for j in $(seq 4 9); do
6761                         echo foo > $dir/$tfile-$j
6762                 done
6763         done
6764
6765         # find mirrored files with specific mirror count
6766         cmd="$LFS find --mirror-count 3 --type f $td"
6767         nfiles=$($cmd | wc -l)
6768         [[ $nfiles = 10 ]] || error "$cmd: $nfiles != 10 files"
6769
6770         cmd="$LFS find ! --mirror-count 3 --type f $td"
6771         nfiles=$($cmd | wc -l)
6772         [[ $nfiles = 20 ]] || error "$cmd: $nfiles != 20 files"
6773
6774         cmd="$LFS find --mirror-count +2 --type f $td"
6775         nfiles=$($cmd | wc -l)
6776         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6777
6778         cmd="$LFS find --mirror-count -6 --type f $td"
6779         nfiles=$($cmd | wc -l)
6780         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6781
6782         # find mirrored files with specific file state
6783         cmd="$LFS find --maxdepth 1 --mirror-state=^ro --type f $td"
6784         [[ $($cmd) = $tf-6 ]] || error "$cmd: didn't return $tf-6"
6785
6786         cmd="$LFS find --mirror-state=ro --type f $td"
6787         nfiles=$($cmd | wc -l)
6788         [[ $nfiles = 17 ]] || error "$cmd: $nfiles != 17 files"
6789
6790         cmd="$LFS find ! --mirror-state=ro --type f $td"
6791         nfiles=$($cmd | wc -l)
6792         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6793
6794         cmd="$LFS find --mirror-state=wp --type f $td"
6795         nfiles=$($cmd | wc -l)
6796         [[ $nfiles = 13 ]] || error "$cmd: $nfiles != 13 files"
6797
6798         cmd="$LFS find ! --mirror-state=sp --type f $td"
6799         nfiles=$($cmd | wc -l)
6800         [[ $nfiles = 30 ]] || error "$cmd: $nfiles != 30 files"
6801 }
6802 run_test 56ca "check lfs find --mirror-count|-N and --mirror-state"
6803
6804 test_57a() {
6805         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6806         # note test will not do anything if MDS is not local
6807         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6808                 skip_env "ldiskfs only test"
6809         fi
6810         remote_mds_nodsh && skip "remote MDS with nodsh"
6811
6812         local MNTDEV="osd*.*MDT*.mntdev"
6813         DEV=$(do_facet $SINGLEMDS lctl get_param -n $MNTDEV)
6814         [ -z "$DEV" ] && error "can't access $MNTDEV"
6815         for DEV in $(do_facet $SINGLEMDS lctl get_param -n $MNTDEV); do
6816                 do_facet $SINGLEMDS $DUMPE2FS -h $DEV > $TMP/t57a.dump ||
6817                         error "can't access $DEV"
6818                 DEVISIZE=$(awk '/Inode size:/ { print $3 }' $TMP/t57a.dump)
6819                 [[ $DEVISIZE -gt 128 ]] || error "inode size $DEVISIZE"
6820                 rm $TMP/t57a.dump
6821         done
6822 }
6823 run_test 57a "verify MDS filesystem created with large inodes =="
6824
6825 test_57b() {
6826         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6827         if [ "$mds1_FSTYPE" != ldiskfs ]; then
6828                 skip_env "ldiskfs only test"
6829         fi
6830         remote_mds_nodsh && skip "remote MDS with nodsh"
6831
6832         local dir=$DIR/$tdir
6833         local filecount=100
6834         local file1=$dir/f1
6835         local fileN=$dir/f$filecount
6836
6837         rm -rf $dir || error "removing $dir"
6838         test_mkdir -c1 $dir
6839         local mdtidx=$($LFS getstripe -m $dir)
6840         local mdtname=MDT$(printf %04x $mdtidx)
6841         local facet=mds$((mdtidx + 1))
6842
6843         echo "mcreating $filecount files"
6844         createmany -m $dir/f 1 $filecount || error "creating files in $dir"
6845
6846         # verify that files do not have EAs yet
6847         $LFS getstripe $file1 2>&1 | grep -q "no stripe" ||
6848                 error "$file1 has an EA"
6849         $LFS getstripe $fileN 2>&1 | grep -q "no stripe" ||
6850                 error "$fileN has an EA"
6851
6852         sync
6853         sleep 1
6854         df $dir  #make sure we get new statfs data
6855         local mdsfree=$(do_facet $facet \
6856                         lctl get_param -n osd*.*$mdtname.kbytesfree)
6857         local mdcfree=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6858         local file
6859
6860         echo "opening files to create objects/EAs"
6861         for file in $(seq -f $dir/f%g 1 $filecount); do
6862                 $OPENFILE -f O_RDWR $file > /dev/null 2>&1 ||
6863                         error "opening $file"
6864         done
6865
6866         # verify that files have EAs now
6867         $LFS getstripe $file1 | grep -q "obdidx" || error "$file1 missing EA"
6868         $LFS getstripe $fileN | grep -q "obdidx" || error "$fileN missing EA"
6869
6870         sleep 1  #make sure we get new statfs data
6871         df $dir
6872         local mdsfree2=$(do_facet $facet \
6873                          lctl get_param -n osd*.*$mdtname.kbytesfree)
6874         local mdcfree2=$(lctl get_param -n mdc.*$mdtname-mdc-*.kbytesfree)
6875
6876         if [[ $mdcfree2 -lt $((mdcfree - 16)) ]]; then
6877                 if [ "$mdsfree" != "$mdsfree2" ]; then
6878                         error "MDC before $mdcfree != after $mdcfree2"
6879                 else
6880                         echo "MDC before $mdcfree != after $mdcfree2"
6881                         echo "unable to confirm if MDS has large inodes"
6882                 fi
6883         fi
6884         rm -rf $dir
6885 }
6886 run_test 57b "default LOV EAs are stored inside large inodes ==="
6887
6888 test_58() {
6889         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6890         [ -z "$(which wiretest 2>/dev/null)" ] &&
6891                         skip_env "could not find wiretest"
6892
6893         wiretest
6894 }
6895 run_test 58 "verify cross-platform wire constants =============="
6896
6897 test_59() {
6898         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6899
6900         echo "touch 130 files"
6901         createmany -o $DIR/f59- 130
6902         echo "rm 130 files"
6903         unlinkmany $DIR/f59- 130
6904         sync
6905         # wait for commitment of removal
6906         wait_delete_completed
6907 }
6908 run_test 59 "verify cancellation of llog records async ========="
6909
6910 TEST60_HEAD="test_60 run $RANDOM"
6911 test_60a() {
6912         [ $PARALLEL == "yes" ] && skip "skip parallel run"
6913         remote_mgs_nodsh && skip "remote MGS with nodsh"
6914         do_facet mgs "! which run-llog.sh &> /dev/null" &&
6915                 do_facet mgs "! ls run-llog.sh &> /dev/null" &&
6916                         skip_env "missing subtest run-llog.sh"
6917
6918         log "$TEST60_HEAD - from kernel mode"
6919         do_facet mgs "$LCTL dk > /dev/null"
6920         do_facet mgs "bash run-llog.sh" || error "run-llog.sh failed"
6921         do_facet mgs $LCTL dk > $TMP/$tfile
6922
6923         # LU-6388: test llog_reader
6924         local llog_reader=$(do_facet mgs "which llog_reader 2> /dev/null")
6925         llog_reader=${llog_reader:-$LUSTRE/utils/llog_reader}
6926         [ -z $(do_facet mgs ls -d $llog_reader 2> /dev/null) ] &&
6927                         skip_env "missing llog_reader"
6928         local fstype=$(facet_fstype mgs)
6929         [ $fstype != ldiskfs -a $fstype != zfs ] &&
6930                 skip_env "Only for ldiskfs or zfs type mgs"
6931
6932         local mntpt=$(facet_mntpt mgs)
6933         local mgsdev=$(mgsdevname 1)
6934         local fid_list
6935         local fid
6936         local rec_list
6937         local rec
6938         local rec_type
6939         local obj_file
6940         local path
6941         local seq
6942         local oid
6943         local pass=true
6944
6945         #get fid and record list
6946         fid_list=($(awk '/9_sub.*record/ { print $NF }' $TMP/$tfile |
6947                 tail -n 4))
6948         rec_list=($(awk '/9_sub.*record/ { print $((NF-3)) }' $TMP/$tfile |
6949                 tail -n 4))
6950         #remount mgs as ldiskfs or zfs type
6951         stop mgs || error "stop mgs failed"
6952         mount_fstype mgs || error "remount mgs failed"
6953         for ((i = 0; i < ${#fid_list[@]}; i++)); do
6954                 fid=${fid_list[i]}
6955                 rec=${rec_list[i]}
6956                 seq=$(echo $fid | awk -F ':' '{ print $1 }' | sed -e "s/^0x//g")
6957                 oid=$(echo $fid | awk -F ':' '{ print $2 }' | sed -e "s/^0x//g")
6958                 oid=$((16#$oid))
6959
6960                 case $fstype in
6961                         ldiskfs )
6962                                 obj_file=$mntpt/O/$seq/d$((oid%32))/$oid ;;
6963                         zfs )
6964                                 obj_file=$mntpt/oi.$(($((16#$seq))&127))/$fid ;;
6965                 esac
6966                 echo "obj_file is $obj_file"
6967                 do_facet mgs $llog_reader $obj_file
6968
6969                 rec_type=$(do_facet mgs $llog_reader $obj_file | grep "type=" |
6970                         awk '{ print $3 }' | sed -e "s/^type=//g")
6971                 if [ $rec_type != $rec ]; then
6972                         echo "FAILED test_60a wrong record type $rec_type," \
6973                               "should be $rec"
6974                         pass=false
6975                         break
6976                 fi
6977
6978                 #check obj path if record type is LLOG_LOGID_MAGIC
6979                 if [ "$rec" == "1064553b" ]; then
6980                         path=$(do_facet mgs $llog_reader $obj_file |
6981                                 grep "path=" | awk '{ print $NF }' |
6982                                 sed -e "s/^path=//g")
6983                         if [ $obj_file != $mntpt/$path ]; then
6984                                 echo "FAILED test_60a wrong obj path" \
6985                                       "$montpt/$path, should be $obj_file"
6986                                 pass=false
6987                                 break
6988                         fi
6989                 fi
6990         done
6991         rm -f $TMP/$tfile
6992         #restart mgs before "error", otherwise it will block the next test
6993         stop mgs || error "stop mgs failed"
6994         start mgs $(mgsdevname) $MGS_MOUNT_OPTS || error "start mgs failed"
6995         $pass || error "test failed, see FAILED test_60a messages for specifics"
6996 }
6997 run_test 60a "llog_test run from kernel module and test llog_reader"
6998
6999 test_60b() { # bug 6411
7000         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7001
7002         dmesg > $DIR/$tfile
7003         LLOG_COUNT=$(do_facet mgs dmesg |
7004                      awk "/$TEST60_HEAD/ { marker = 1; from_marker = 0; }
7005                           /llog_[a-z]*.c:[0-9]/ {
7006                                 if (marker)
7007                                         from_marker++
7008                                 from_begin++
7009                           }
7010                           END {
7011                                 if (marker)
7012                                         print from_marker
7013                                 else
7014                                         print from_begin
7015                           }")
7016
7017         [[ $LLOG_COUNT -gt 120 ]] &&
7018                 error "CDEBUG_LIMIT not limiting messages ($LLOG_COUNT)" || true
7019 }
7020 run_test 60b "limit repeated messages from CERROR/CWARN"
7021
7022 test_60c() {
7023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7024
7025         echo "create 5000 files"
7026         createmany -o $DIR/f60c- 5000
7027 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED  0x137
7028         lctl set_param fail_loc=0x80000137
7029         unlinkmany $DIR/f60c- 5000
7030         lctl set_param fail_loc=0
7031 }
7032 run_test 60c "unlink file when mds full"
7033
7034 test_60d() {
7035         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7036
7037         SAVEPRINTK=$(lctl get_param -n printk)
7038         # verify "lctl mark" is even working"
7039         MESSAGE="test message ID $RANDOM $$"
7040         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7041         dmesg | grep -q "$MESSAGE" || error "didn't find debug marker in log"
7042
7043         lctl set_param printk=0 || error "set lnet.printk failed"
7044         lctl get_param -n printk | grep emerg || error "lnet.printk dropped emerg"
7045         MESSAGE="new test message ID $RANDOM $$"
7046         # Assume here that libcfs_debug_mark_buffer() uses D_WARNING
7047         $LCTL mark "$MESSAGE" || error "$LCTL mark failed"
7048         dmesg | grep -q "$MESSAGE" && error "D_WARNING wasn't masked" || true
7049
7050         lctl set_param -n printk="$SAVEPRINTK"
7051 }
7052 run_test 60d "test printk console message masking"
7053
7054 test_60e() {
7055         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7056         remote_mds_nodsh && skip "remote MDS with nodsh"
7057
7058         touch $DIR/$tfile
7059 #define OBD_FAIL_MDS_LLOG_CREATE_FAILED2  0x15b
7060         do_facet mds1 lctl set_param fail_loc=0x15b
7061         rm $DIR/$tfile
7062 }
7063 run_test 60e "no space while new llog is being created"
7064
7065 test_60g() {
7066         local pid
7067         local i
7068
7069         test_mkdir -c $MDSCOUNT $DIR/$tdir
7070
7071         (
7072                 local index=0
7073                 while true; do
7074                         $LFS setdirstripe -i $(($index % $MDSCOUNT)) \
7075                                 -c $MDSCOUNT $DIR/$tdir/subdir$index \
7076                                 2>/dev/null
7077                         mkdir $DIR/$tdir/subdir$index 2>/dev/null
7078                         rmdir $DIR/$tdir/subdir$index 2>/dev/null
7079                         index=$((index + 1))
7080                 done
7081         ) &
7082
7083         pid=$!
7084
7085         for i in {0..100}; do
7086                 # define OBD_FAIL_OSD_TXN_START    0x19a
7087                 local index=$((i % MDSCOUNT + 1))
7088
7089                 do_facet mds$index $LCTL set_param fail_loc=0x8000019a \
7090                         > /dev/null
7091                 usleep 100
7092         done
7093
7094         kill -9 $pid
7095
7096         for i in $(seq $MDSCOUNT); do
7097                 do_facet mds$i $LCTL set_param fail_loc=0 > /dev/null
7098         done
7099
7100         mkdir $DIR/$tdir/new || error "mkdir failed"
7101         rmdir $DIR/$tdir/new || error "rmdir failed"
7102
7103         do_facet mds1 $LCTL lfsck_start -M $(facet_svc mds1) -A -C \
7104                 -t namespace
7105         for i in $(seq $MDSCOUNT); do
7106                 wait_update_facet mds$i "$LCTL get_param -n \
7107                         mdd.$(facet_svc mds$i).lfsck_namespace |
7108                         awk '/^status/ { print \\\$2 }'" "completed"
7109         done
7110
7111         ls -R $DIR/$tdir || error "ls failed"
7112         rm -rf $DIR/$tdir || error "rmdir failed"
7113 }
7114 run_test 60g "transaction abort won't cause MDT hung"
7115
7116 test_60h() {
7117         [ $MDS1_VERSION -le $(version_code 2.12.52) ] &&
7118                 skip "Need MDS version at least 2.12.52"
7119         [ $MDSCOUNT -lt 2 ] && skip "Need at least 2 MDTs"
7120
7121         local f
7122
7123         #define OBD_FAIL_MDS_STRIPE_CREATE       0x188
7124         #define OBD_FAIL_MDS_STRIPE_FID          0x189
7125         for fail_loc in 0x80000188 0x80000189; do
7126                 do_facet mds1 "$LCTL set_param fail_loc=$fail_loc"
7127                 $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir-$fail_loc ||
7128                         error "mkdir $dir-$fail_loc failed"
7129                 for i in {0..10}; do
7130                         # create may fail on missing stripe
7131                         echo $i > $DIR/$tdir-$fail_loc/$i
7132                 done
7133                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7134                         error "getdirstripe $tdir-$fail_loc failed"
7135                 $LFS migrate -m 1 $DIR/$tdir-$fail_loc ||
7136                         error "migrate $tdir-$fail_loc failed"
7137                 $LFS getdirstripe $DIR/$tdir-$fail_loc ||
7138                         error "getdirstripe $tdir-$fail_loc failed"
7139                 pushd $DIR/$tdir-$fail_loc
7140                 for f in *; do
7141                         echo $f | cmp $f - || error "$f data mismatch"
7142                 done
7143                 popd
7144                 rm -rf $DIR/$tdir-$fail_loc
7145         done
7146 }
7147 run_test 60h "striped directory with missing stripes can be accessed"
7148
7149 test_61a() {
7150         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7151
7152         f="$DIR/f61"
7153         dd if=/dev/zero of=$f bs=$PAGE_SIZE count=1 || error "dd $f failed"
7154         cancel_lru_locks osc
7155         $MULTIOP $f OSMWUc || error "$MULTIOP $f failed"
7156         sync
7157 }
7158 run_test 61a "mmap() writes don't make sync hang ================"
7159
7160 test_61b() {
7161         mmap_mknod_test $DIR/$tfile || error "mmap_mknod_test failed"
7162 }
7163 run_test 61b "mmap() of unstriped file is successful"
7164
7165 # bug 2330 - insufficient obd_match error checking causes LBUG
7166 test_62() {
7167         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7168
7169         f="$DIR/f62"
7170         echo foo > $f
7171         cancel_lru_locks osc
7172         lctl set_param fail_loc=0x405
7173         cat $f && error "cat succeeded, expect -EIO"
7174         lctl set_param fail_loc=0
7175 }
7176 # This test is now irrelevant (as of bug 10718 inclusion), we no longer
7177 # match every page all of the time.
7178 #run_test 62 "verify obd_match failure doesn't LBUG (should -EIO)"
7179
7180 # bug 2319 - oig_wait() interrupted causes crash because of invalid waitq.
7181 # Though this test is irrelevant anymore, it helped to reveal some
7182 # other grant bugs (LU-4482), let's keep it.
7183 test_63a() {   # was test_63
7184         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7185
7186         MAX_DIRTY_MB=$(lctl get_param -n osc.*.max_dirty_mb | head -n 1)
7187
7188         for i in `seq 10` ; do
7189                 dd if=/dev/zero of=$DIR/f63 bs=8k &
7190                 sleep 5
7191                 kill $!
7192                 sleep 1
7193         done
7194
7195         rm -f $DIR/f63 || true
7196 }
7197 run_test 63a "Verify oig_wait interruption does not crash ======="
7198
7199 # bug 2248 - async write errors didn't return to application on sync
7200 # bug 3677 - async write errors left page locked
7201 test_63b() {
7202         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7203
7204         debugsave
7205         lctl set_param debug=-1
7206
7207         # ensure we have a grant to do async writes
7208         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1
7209         rm $DIR/$tfile
7210
7211         sync    # sync lest earlier test intercept the fail_loc
7212
7213         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
7214         lctl set_param fail_loc=0x80000406
7215         $MULTIOP $DIR/$tfile Owy && \
7216                 error "sync didn't return ENOMEM"
7217         sync; sleep 2; sync     # do a real sync this time to flush page
7218         lctl get_param -n llite.*.dump_page_cache | grep locked && \
7219                 error "locked page left in cache after async error" || true
7220         debugrestore
7221 }
7222 run_test 63b "async write errors should be returned to fsync ==="
7223
7224 test_64a () {
7225         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7226
7227         df $DIR
7228         lctl get_param -n osc.*[oO][sS][cC][_-]*.cur* | grep "[0-9]"
7229 }
7230 run_test 64a "verify filter grant calculations (in kernel) ====="
7231
7232 test_64b () {
7233         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7234
7235         sh oos.sh $MOUNT || error "oos.sh failed: $?"
7236 }
7237 run_test 64b "check out-of-space detection on client"
7238
7239 test_64c() {
7240         $LCTL set_param osc.*OST0000-osc-[^mM]*.cur_grant_bytes=0
7241 }
7242 run_test 64c "verify grant shrink"
7243
7244 # this does exactly what osc_request.c:osc_announce_cached() does in
7245 # order to calculate max amount of grants to ask from server
7246 want_grant() {
7247         local tgt=$1
7248
7249         local nrpages=$($LCTL get_param -n osc.${tgt}.max_pages_per_rpc)
7250         local rpc_in_flight=$($LCTL get_param -n osc.${tgt}.max_rpcs_in_flight)
7251
7252         ((rpc_in_flight ++));
7253         nrpages=$((nrpages * rpc_in_flight))
7254
7255         local dirty_max_pages=$($LCTL get_param -n osc.${tgt}.max_dirty_mb)
7256
7257         dirty_max_pages=$((dirty_max_pages * 1024 * 1024 / PAGE_SIZE))
7258
7259         [[ $dirty_max_pages -gt $nrpages ]] && nrpages=$dirty_max_pages
7260         local undirty=$((nrpages * PAGE_SIZE))
7261
7262         local max_extent_pages
7263         max_extent_pages=$($LCTL get_param osc.${tgt}.import |
7264             grep grant_max_extent_size | awk '{print $2}')
7265         max_extent_pages=$((max_extent_pages / PAGE_SIZE))
7266         local nrextents=$(((nrpages + max_extent_pages - 1) / max_extent_pages))
7267         local grant_extent_tax
7268         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7269             grep grant_extent_tax | awk '{print $2}')
7270
7271         undirty=$((undirty + nrextents * grant_extent_tax))
7272
7273         echo $undirty
7274 }
7275
7276 # this is size of unit for grant allocation. It should be equal to
7277 # what tgt_grant.c:tgt_grant_chunk() calculates
7278 grant_chunk() {
7279         local tgt=$1
7280         local max_brw_size
7281         local grant_extent_tax
7282
7283         max_brw_size=$($LCTL get_param osc.${tgt}.import |
7284             grep max_brw_size | awk '{print $2}')
7285
7286         grant_extent_tax=$($LCTL get_param osc.${tgt}.import |
7287             grep grant_extent_tax | awk '{print $2}')
7288
7289         echo $(((max_brw_size + grant_extent_tax) * 2))
7290 }
7291
7292 test_64d() {
7293         [ $OST1_VERSION -lt $(version_code 2.10.56) ] &&
7294                 skip "OST < 2.10.55 doesn't limit grants enough"
7295
7296         local tgt=$($LCTL dl | grep "0000-osc-[^mM]" | awk '{print $4}')
7297         local file=$DIR/$tfile
7298
7299         [[ $($LCTL get_param osc.${tgt}.import |
7300              grep "connect_flags:.*grant_param") ]] ||
7301                 skip "no grant_param connect flag"
7302
7303         local olddebug=$($LCTL get_param -n debug 2> /dev/null)
7304
7305         $LCTL set_param debug="$OLDDEBUG" 2> /dev/null || true
7306
7307         local max_cur_granted=$(($(want_grant $tgt) + $(grant_chunk $tgt)))
7308         stack_trap "rm -f $file" EXIT
7309
7310         $LFS setstripe $file -i 0 -c 1
7311         dd if=/dev/zero of=$file bs=1M count=1000 &
7312         ddpid=$!
7313
7314         while true
7315         do
7316                 local cur_grant=$($LCTL get_param -n osc.${tgt}.cur_grant_bytes)
7317                 if [[ $cur_grant -gt $max_cur_granted ]]
7318                 then
7319                         kill $ddpid
7320                         error "cur_grant $cur_grant > $max_cur_granted"
7321                 fi
7322                 kill -0 $ddpid
7323                 [[ $? -ne 0 ]] && break;
7324                 sleep 2
7325         done
7326
7327         rm -f $DIR/$tfile
7328         wait_delete_completed
7329         $LCTL set_param debug="$olddebug" 2> /dev/null || true
7330 }
7331 run_test 64d "check grant limit exceed"
7332
7333 # bug 1414 - set/get directories' stripe info
7334 test_65a() {
7335         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7336
7337         test_mkdir $DIR/$tdir
7338         touch $DIR/$tdir/f1
7339         $LVERIFY $DIR/$tdir $DIR/$tdir/f1 || error "lverify failed"
7340 }
7341 run_test 65a "directory with no stripe info"
7342
7343 test_65b() {
7344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7345
7346         test_mkdir $DIR/$tdir
7347         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7348
7349         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7350                                                 error "setstripe"
7351         touch $DIR/$tdir/f2
7352         $LVERIFY $DIR/$tdir $DIR/$tdir/f2 || error "lverify failed"
7353 }
7354 run_test 65b "directory setstripe -S stripe_size*2 -i 0 -c 1"
7355
7356 test_65c() {
7357         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7358         [ $OSTCOUNT -lt 2 ] && skip_env "need at least 2 OSTs"
7359
7360         test_mkdir $DIR/$tdir
7361         local stripesize=$($LFS getstripe -S $DIR/$tdir)
7362
7363         $LFS setstripe -S $((stripesize * 4)) -i 1 \
7364                 -c $((OSTCOUNT - 1)) $DIR/$tdir || error "setstripe"
7365         touch $DIR/$tdir/f3
7366         $LVERIFY $DIR/$tdir $DIR/$tdir/f3 || error "lverify failed"
7367 }
7368 run_test 65c "directory setstripe -S stripe_size*4 -i 1 -c $((OSTCOUNT-1))"
7369
7370 test_65d() {
7371         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7372
7373         test_mkdir $DIR/$tdir
7374         local STRIPECOUNT=$($LFS getstripe -c $DIR/$tdir)
7375         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7376
7377         if [[ $STRIPECOUNT -le 0 ]]; then
7378                 sc=1
7379         elif [[ $STRIPECOUNT -gt $LOV_MAX_STRIPE_COUNT ]]; then
7380                 [[ $OSTCOUNT -gt $LOV_MAX_STRIPE_COUNT ]] &&
7381                         sc=$LOV_MAX_STRIPE_COUNT || sc=$(($OSTCOUNT - 1))
7382         else
7383                 sc=$(($STRIPECOUNT - 1))
7384         fi
7385         $LFS setstripe -S $STRIPESIZE -c $sc $DIR/$tdir || error "setstripe"
7386         touch $DIR/$tdir/f4 $DIR/$tdir/f5
7387         $LVERIFY $DIR/$tdir $DIR/$tdir/f4 $DIR/$tdir/f5 ||
7388                 error "lverify failed"
7389 }
7390 run_test 65d "directory setstripe -S stripe_size -c stripe_count"
7391
7392 test_65e() {
7393         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7394
7395         test_mkdir $DIR/$tdir
7396
7397         $LFS setstripe $DIR/$tdir || error "setstripe"
7398         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7399                                         error "no stripe info failed"
7400         touch $DIR/$tdir/f6
7401         $LVERIFY $DIR/$tdir $DIR/$tdir/f6 || error "lverify failed"
7402 }
7403 run_test 65e "directory setstripe defaults"
7404
7405 test_65f() {
7406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7407
7408         test_mkdir $DIR/${tdir}f
7409         $RUNAS $LFS setstripe $DIR/${tdir}f &&
7410                 error "setstripe succeeded" || true
7411 }
7412 run_test 65f "dir setstripe permission (should return error) ==="
7413
7414 test_65g() {
7415         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7416
7417         test_mkdir $DIR/$tdir
7418         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7419
7420         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7421                 error "setstripe -S failed"
7422         $LFS setstripe -d $DIR/$tdir || error "setstripe -d failed"
7423         $LFS getstripe -v $DIR/$tdir | grep "Default" ||
7424                 error "delete default stripe failed"
7425 }
7426 run_test 65g "directory setstripe -d"
7427
7428 test_65h() {
7429         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7430
7431         test_mkdir $DIR/$tdir
7432         local STRIPESIZE=$($LFS getstripe -S $DIR/$tdir)
7433
7434         $LFS setstripe -S $((STRIPESIZE * 2)) -i 0 -c 1 $DIR/$tdir ||
7435                 error "setstripe -S failed"
7436         test_mkdir $DIR/$tdir/dd1
7437         [ $($LFS getstripe -c $DIR/$tdir) = $($LFS getstripe -c $DIR/$tdir/dd1) ] ||
7438                 error "stripe info inherit failed"
7439 }
7440 run_test 65h "directory stripe info inherit ===================="
7441
7442 test_65i() {
7443         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7444
7445         save_layout_restore_at_exit $MOUNT
7446
7447         # bug6367: set non-default striping on root directory
7448         $LFS setstripe -S 65536 -c -1 $MOUNT || error "error setting stripe"
7449
7450         # bug12836: getstripe on -1 default directory striping
7451         $LFS getstripe $MOUNT || error "getstripe $MOUNT failed"
7452
7453         # bug12836: getstripe -v on -1 default directory striping
7454         $LFS getstripe -v $MOUNT || error "getstripe -v $MOUNT failed"
7455
7456         # bug12836: new find on -1 default directory striping
7457         $LFS find -mtime -1 $MOUNT > /dev/null || error "find $MOUNT failed"
7458 }
7459 run_test 65i "various tests to set root directory striping"
7460
7461 test_65j() { # bug6367
7462         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7463
7464         sync; sleep 1
7465
7466         # if we aren't already remounting for each test, do so for this test
7467         if [ "$I_MOUNTED" = "yes" ]; then
7468                 cleanup || error "failed to unmount"
7469                 setup
7470         fi
7471
7472         save_layout_restore_at_exit $MOUNT
7473
7474         $LFS setstripe -d $MOUNT || error "setstripe failed"
7475 }
7476 run_test 65j "set default striping on root directory (bug 6367)="
7477
7478 cleanup_65k() {
7479         rm -rf $DIR/$tdir
7480         wait_delete_completed
7481         do_facet $SINGLEMDS "lctl set_param -n \
7482                 osp.$ost*MDT0000.max_create_count=$max_count"
7483         do_facet $SINGLEMDS "lctl set_param -n \
7484                 osp.$ost*MDT0000.create_count=$count"
7485         do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7486         echo $INACTIVE_OSC "is Activate"
7487
7488         wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7489 }
7490
7491 test_65k() { # bug11679
7492         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7493         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
7494         remote_mds_nodsh && skip "remote MDS with nodsh"
7495
7496         local disable_precreate=true
7497         [ $MDS1_VERSION -le $(version_code 2.8.54) ] &&
7498                 disable_precreate=false
7499
7500         echo "Check OST status: "
7501         local MDS_OSCS=$(do_facet $SINGLEMDS lctl dl |
7502                 awk '/[oO][sS][cC].*md[ts]/ { print $4 }')
7503
7504         for OSC in $MDS_OSCS; do
7505                 echo $OSC "is active"
7506                 do_facet $SINGLEMDS lctl --device %$OSC activate
7507         done
7508
7509         for INACTIVE_OSC in $MDS_OSCS; do
7510                 local ost=$(osc_to_ost $INACTIVE_OSC)
7511                 local ostnum=$(do_facet $SINGLEMDS lctl get_param -n \
7512                                lov.*md*.target_obd |
7513                                awk -F: /$ost/'{ print $1 }' | head -n 1)
7514
7515                 mkdir -p $DIR/$tdir
7516                 $LFS setstripe -i $ostnum -c 1 $DIR/$tdir
7517                 createmany -o $DIR/$tdir/$tfile.$ostnum. 1000
7518
7519                 echo "Deactivate: " $INACTIVE_OSC
7520                 do_facet $SINGLEMDS lctl --device %$INACTIVE_OSC deactivate
7521
7522                 local count=$(do_facet $SINGLEMDS "lctl get_param -n \
7523                               osp.$ost*MDT0000.create_count")
7524                 local max_count=$(do_facet $SINGLEMDS "lctl get_param -n \
7525                                   osp.$ost*MDT0000.max_create_count")
7526                 $disable_precreate &&
7527                         do_facet $SINGLEMDS "lctl set_param -n \
7528                                 osp.$ost*MDT0000.max_create_count=0"
7529
7530                 for idx in $(seq 0 $((OSTCOUNT - 1))); do
7531                         [ -f $DIR/$tdir/$idx ] && continue
7532                         echo "$LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx"
7533                         $LFS setstripe -i $idx -c 1 $DIR/$tdir/$idx ||
7534                                 { cleanup_65k;
7535                                   error "setstripe $idx should succeed"; }
7536                         rm -f $DIR/$tdir/$idx || error "rm $idx failed"
7537                 done
7538                 unlinkmany $DIR/$tdir/$tfile.$ostnum. 1000
7539                 rmdir $DIR/$tdir
7540
7541                 do_facet $SINGLEMDS "lctl set_param -n \
7542                         osp.$ost*MDT0000.max_create_count=$max_count"
7543                 do_facet $SINGLEMDS "lctl set_param -n \
7544                         osp.$ost*MDT0000.create_count=$count"
7545                 do_facet $SINGLEMDS lctl --device  %$INACTIVE_OSC activate
7546                 echo $INACTIVE_OSC "is Activate"
7547
7548                 wait_osc_import_state mds ost$(( ostnum + 1 )) FULL
7549         done
7550 }
7551 run_test 65k "validate manual striping works properly with deactivated OSCs"
7552
7553 test_65l() { # bug 12836
7554         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7555
7556         test_mkdir -p $DIR/$tdir/test_dir
7557         $LFS setstripe -c -1 $DIR/$tdir/test_dir
7558         $LFS find -mtime -1 $DIR/$tdir >/dev/null
7559 }
7560 run_test 65l "lfs find on -1 stripe dir ========================"
7561
7562 test_65m() {
7563         local layout=$(save_layout $MOUNT)
7564         $RUNAS $LFS setstripe -c 2 $MOUNT && {
7565                 restore_layout $MOUNT $layout
7566                 error "setstripe should fail by non-root users"
7567         }
7568         true
7569 }
7570 run_test 65m "normal user can't set filesystem default stripe"
7571
7572 test_65n() {
7573         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
7574         [[ $(lustre_version_code $SINGLEMDS) -ge $(version_code 2.12.50) ]] ||
7575                 skip "Need MDS version at least 2.12.50"
7576         [[ $PARALLEL != "yes" ]] || skip "skip parallel run"
7577
7578         [[ $OSTCOUNT -ge 2 ]] || skip_env "needs >= 2 OSTs"
7579         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
7580         which setfattr > /dev/null 2>&1 || skip_env "no setfattr command"
7581
7582         local root_layout=$(save_layout $MOUNT)
7583         stack_trap "restore_layout $MOUNT $root_layout" EXIT
7584
7585         # new subdirectory under root directory should not inherit
7586         # the default layout from root
7587         local dir1=$MOUNT/$tdir-1
7588         mkdir $dir1 || error "mkdir $dir1 failed"
7589         ! getfattr -n trusted.lov $dir1 &> /dev/null ||
7590                 error "$dir1 shouldn't have LOV EA"
7591
7592         # delete the default layout on root directory
7593         $LFS setstripe -d $MOUNT || error "delete root default layout failed"
7594
7595         local dir2=$MOUNT/$tdir-2
7596         mkdir $dir2 || error "mkdir $dir2 failed"
7597         ! getfattr -n trusted.lov $dir2 &> /dev/null ||
7598                 error "$dir2 shouldn't have LOV EA"
7599
7600         # set a new striping pattern on root directory
7601         local def_stripe_size=$($LFS getstripe -S $MOUNT)
7602         local new_def_stripe_size=$((def_stripe_size * 2))
7603         $LFS setstripe -S $new_def_stripe_size $MOUNT ||
7604                 error "set stripe size on $MOUNT failed"
7605
7606         # new file created in $dir2 should inherit the new stripe size from
7607         # the filesystem default
7608         local file2=$dir2/$tfile-2
7609         touch $file2 || error "touch $file2 failed"
7610
7611         local file2_stripe_size=$($LFS getstripe -S $file2)
7612         [[ $file2_stripe_size -eq $new_def_stripe_size ]] ||
7613                 error "$file2 didn't inherit stripe size $new_def_stripe_size"
7614
7615         local dir3=$MOUNT/$tdir-3
7616         mkdir $dir3 || error "mkdir $dir3 failed"
7617         ! getfattr -n trusted.lov $dir3 &> /dev/null ||
7618                 error "$dir3 shouldn't have LOV EA"
7619
7620         # set OST pool on root directory
7621         local pool=$TESTNAME
7622         pool_add $pool || error "add $pool failed"
7623         pool_add_targets $pool 0 $((OSTCOUNT - 1)) 1 ||
7624                 error "add targets to $pool failed"
7625
7626         $LFS setstripe -p $pool $MOUNT ||
7627                 error "set OST pool on $MOUNT failed"
7628
7629         # new file created in $dir3 should inherit the pool from
7630         # the filesystem default
7631         local file3=$dir3/$tfile-3
7632         touch $file3 || error "touch $file3 failed"
7633
7634         local file3_pool=$($LFS getstripe -p $file3)
7635         [[ "$file3_pool" = "$pool" ]] ||
7636                 error "$file3 didn't inherit OST pool $pool"
7637
7638         local dir4=$MOUNT/$tdir-4
7639         mkdir $dir4 || error "mkdir $dir4 failed"
7640         ! getfattr -n trusted.lov $dir4 &> /dev/null ||
7641                 error "$dir4 shouldn't have LOV EA"
7642
7643         # new file created in $dir4 should inherit the pool from
7644         # the filesystem default
7645         local file4=$dir4/$tfile-4
7646         touch $file4 || error "touch $file4 failed"
7647
7648         local file4_pool=$($LFS getstripe -p $file4)
7649         [[ "$file4_pool" = "$pool" ]] ||
7650                 error "$file4 didn't inherit OST pool $pool"
7651
7652         # new subdirectory under non-root directory should inherit
7653         # the default layout from its parent directory
7654         $LFS setstripe -S $new_def_stripe_size -p $pool $dir4 ||
7655                 error "set directory layout on $dir4 failed"
7656
7657         local dir5=$dir4/$tdir-5
7658         mkdir $dir5 || error "mkdir $dir5 failed"
7659
7660         local dir4_layout=$(get_layout_param $dir4)
7661         local dir5_layout=$(get_layout_param $dir5)
7662         [[ "$dir4_layout" = "$dir5_layout" ]] ||
7663                 error "$dir5 should inherit the default layout from $dir4"
7664 }
7665 run_test 65n "don't inherit default layout from root for new subdirectories"
7666
7667 # bug 2543 - update blocks count on client
7668 test_66() {
7669         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7670
7671         COUNT=${COUNT:-8}
7672         dd if=/dev/zero of=$DIR/f66 bs=1k count=$COUNT
7673         sync; sync_all_data; sync; sync_all_data
7674         cancel_lru_locks osc
7675         BLOCKS=`ls -s $DIR/f66 | awk '{ print $1 }'`
7676         [ $BLOCKS -ge $COUNT ] || error "$DIR/f66 blocks $BLOCKS < $COUNT"
7677 }
7678 run_test 66 "update inode blocks count on client ==============="
7679
7680 meminfo() {
7681         awk '($1 == "'$1':") { print $2 }' /proc/meminfo
7682 }
7683
7684 swap_used() {
7685         swapon -s | awk '($1 == "'$1'") { print $4 }'
7686 }
7687
7688 # bug5265, obdfilter oa2dentry return -ENOENT
7689 # #define OBD_FAIL_SRV_ENOENT 0x217
7690 test_69() {
7691         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7692         remote_ost_nodsh && skip "remote OST with nodsh"
7693
7694         f="$DIR/$tfile"
7695         $LFS setstripe -c 1 -i 0 $f
7696
7697         $DIRECTIO write ${f}.2 0 1 || error "directio write error"
7698
7699         do_facet ost1 lctl set_param fail_loc=0x217
7700         $TRUNCATE $f 1 # vmtruncate() will ignore truncate() error.
7701         $DIRECTIO write $f 0 2 && error "write succeeded, expect -ENOENT"
7702
7703         do_facet ost1 lctl set_param fail_loc=0
7704         $DIRECTIO write $f 0 2 || error "write error"
7705
7706         cancel_lru_locks osc
7707         $DIRECTIO read $f 0 1 || error "read error"
7708
7709         do_facet ost1 lctl set_param fail_loc=0x217
7710         $DIRECTIO read $f 1 1 && error "read succeeded, expect -ENOENT"
7711
7712         do_facet ost1 lctl set_param fail_loc=0
7713         rm -f $f
7714 }
7715 run_test 69 "verify oa2dentry return -ENOENT doesn't LBUG ======"
7716
7717 test_71() {
7718         test_mkdir $DIR/$tdir
7719         $LFS setdirstripe -D -c$MDSCOUNT $DIR/$tdir
7720         sh rundbench -C -D $DIR/$tdir 2 || error "dbench failed!"
7721 }
7722 run_test 71 "Running dbench on lustre (don't segment fault) ===="
7723
7724 test_72a() { # bug 5695 - Test that on 2.6 remove_suid works properly
7725         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7726         [ "$RUNAS_ID" = "$UID" ] &&
7727                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7728         # Check that testing environment is properly set up. Skip if not
7729         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_GID $RUNAS ||
7730                 skip_env "User $RUNAS_ID does not exist - skipping"
7731
7732         touch $DIR/$tfile
7733         chmod 777 $DIR/$tfile
7734         chmod ug+s $DIR/$tfile
7735         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=512 count=1 ||
7736                 error "$RUNAS dd $DIR/$tfile failed"
7737         # See if we are still setuid/sgid
7738         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7739                 error "S/gid is not dropped on write"
7740         # Now test that MDS is updated too
7741         cancel_lru_locks mdc
7742         [ -u $DIR/$tfile ] || [ -g $DIR/$tfile ] &&
7743                 error "S/gid is not dropped on MDS"
7744         rm -f $DIR/$tfile
7745 }
7746 run_test 72a "Test that remove suid works properly (bug5695) ===="
7747
7748 test_72b() { # bug 24226 -- keep mode setting when size is not changing
7749         local perm
7750
7751         [ "$RUNAS_ID" = "$UID" ] &&
7752                 skip_env "RUNAS_ID = UID = $UID -- skipping"
7753         [ "$RUNAS_ID" -eq 0 ] &&
7754                 skip_env "RUNAS_ID = 0 -- skipping"
7755         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7756         # Check that testing environment is properly set up. Skip if not
7757         FAIL_ON_ERROR=false check_runas_id_ret $RUNAS_ID $RUNAS_ID $RUNAS ||
7758                 skip_env "User $RUNAS_ID does not exist - skipping"
7759
7760         touch $DIR/${tfile}-f{g,u}
7761         test_mkdir $DIR/${tfile}-dg
7762         test_mkdir $DIR/${tfile}-du
7763         chmod 770 $DIR/${tfile}-{f,d}{g,u}
7764         chmod g+s $DIR/${tfile}-{f,d}g
7765         chmod u+s $DIR/${tfile}-{f,d}u
7766         for perm in 777 2777 4777; do
7767                 $RUNAS chmod $perm $DIR/${tfile}-fg && error "S/gid file allowed improper chmod to $perm"
7768                 $RUNAS chmod $perm $DIR/${tfile}-fu && error "S/uid file allowed improper chmod to $perm"
7769                 $RUNAS chmod $perm $DIR/${tfile}-dg && error "S/gid dir allowed improper chmod to $perm"
7770                 $RUNAS chmod $perm $DIR/${tfile}-du && error "S/uid dir allowed improper chmod to $perm"
7771         done
7772         true
7773 }
7774 run_test 72b "Test that we keep mode setting if without file data changed (bug 24226)"
7775
7776 # bug 3462 - multiple simultaneous MDC requests
7777 test_73() {
7778         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7779
7780         test_mkdir $DIR/d73-1
7781         test_mkdir $DIR/d73-2
7782         multiop_bg_pause $DIR/d73-1/f73-1 O_c || return 1
7783         pid1=$!
7784
7785         lctl set_param fail_loc=0x80000129
7786         $MULTIOP $DIR/d73-1/f73-2 Oc &
7787         sleep 1
7788         lctl set_param fail_loc=0
7789
7790         $MULTIOP $DIR/d73-2/f73-3 Oc &
7791         pid3=$!
7792
7793         kill -USR1 $pid1
7794         wait $pid1 || return 1
7795
7796         sleep 25
7797
7798         $CHECKSTAT -t file $DIR/d73-1/f73-1 || return 4
7799         $CHECKSTAT -t file $DIR/d73-1/f73-2 || return 5
7800         $CHECKSTAT -t file $DIR/d73-2/f73-3 || return 6
7801
7802         rm -rf $DIR/d73-*
7803 }
7804 run_test 73 "multiple MDC requests (should not deadlock)"
7805
7806 test_74a() { # bug 6149, 6184
7807         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7808
7809         touch $DIR/f74a
7810         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7811         #
7812         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7813         # will spin in a tight reconnection loop
7814         $LCTL set_param fail_loc=0x8000030e
7815         # get any lock that won't be difficult - lookup works.
7816         ls $DIR/f74a
7817         $LCTL set_param fail_loc=0
7818         rm -f $DIR/f74a
7819         true
7820 }
7821 run_test 74a "ldlm_enqueue freed-export error path, ls (shouldn't LBUG)"
7822
7823 test_74b() { # bug 13310
7824         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7825
7826         #define OBD_FAIL_LDLM_ENQUEUE_OLD_EXPORT 0x30e
7827         #
7828         # very important to OR with OBD_FAIL_ONCE (0x80000000) -- otherwise it
7829         # will spin in a tight reconnection loop
7830         $LCTL set_param fail_loc=0x8000030e
7831         # get a "difficult" lock
7832         touch $DIR/f74b
7833         $LCTL set_param fail_loc=0
7834         rm -f $DIR/f74b
7835         true
7836 }
7837 run_test 74b "ldlm_enqueue freed-export error path, touch (shouldn't LBUG)"
7838
7839 test_74c() {
7840         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7841
7842         #define OBD_FAIL_LDLM_NEW_LOCK
7843         $LCTL set_param fail_loc=0x319
7844         touch $DIR/$tfile && error "touch successful"
7845         $LCTL set_param fail_loc=0
7846         true
7847 }
7848 run_test 74c "ldlm_lock_create error path, (shouldn't LBUG)"
7849
7850 num_inodes() {
7851         awk '/lustre_inode_cache/ {print $2; exit}' /proc/slabinfo
7852 }
7853
7854 test_76() { # Now for bug 20433, added originally in bug 1443
7855         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7856
7857         local CPUS=$(getconf _NPROCESSORS_ONLN 2>/dev/null)
7858
7859         cancel_lru_locks osc
7860         BEFORE_INODES=$(num_inodes)
7861         echo "before inodes: $BEFORE_INODES"
7862         local COUNT=1000
7863         [ "$SLOW" = "no" ] && COUNT=100
7864         for i in $(seq $COUNT); do
7865                 touch $DIR/$tfile
7866                 rm -f $DIR/$tfile
7867         done
7868         cancel_lru_locks osc
7869         AFTER_INODES=$(num_inodes)
7870         echo "after inodes: $AFTER_INODES"
7871         local wait=0
7872         while [[ $((AFTER_INODES-1*${CPUS:-1})) -gt $BEFORE_INODES ]]; do
7873                 sleep 2
7874                 AFTER_INODES=$(num_inodes)
7875                 wait=$((wait+2))
7876                 echo "wait $wait seconds inodes: $AFTER_INODES"
7877                 if [ $wait -gt 30 ]; then
7878                         error "inode slab grew from $BEFORE_INODES to $AFTER_INODES"
7879                 fi
7880         done
7881 }
7882 run_test 76 "confirm clients recycle inodes properly ===="
7883
7884
7885 export ORIG_CSUM=""
7886 set_checksums()
7887 {
7888         # Note: in sptlrpc modes which enable its own bulk checksum, the
7889         # original crc32_le bulk checksum will be automatically disabled,
7890         # and the OBD_FAIL_OSC_CHECKSUM_SEND/OBD_FAIL_OSC_CHECKSUM_RECEIVE
7891         # will be checked by sptlrpc code against sptlrpc bulk checksum.
7892         # In this case set_checksums() will not be no-op, because sptlrpc
7893         # bulk checksum will be enabled all through the test.
7894
7895         [ "$ORIG_CSUM" ] || ORIG_CSUM=`lctl get_param -n osc.*.checksums | head -n1`
7896         lctl set_param -n osc.*.checksums $1
7897         return 0
7898 }
7899
7900 export ORIG_CSUM_TYPE="`lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7901                         sed 's/.*\[\(.*\)\].*/\1/g' | head -n1`"
7902 CKSUM_TYPES=${CKSUM_TYPES:-$(lctl get_param -n osc.*osc-[^mM]*.checksum_type |
7903                              tr -d [] | head -n1)}
7904 set_checksum_type()
7905 {
7906         lctl set_param -n osc.*osc-[^mM]*.checksum_type $1
7907         rc=$?
7908         log "set checksum type to $1, rc = $rc"
7909         return $rc
7910 }
7911
7912 get_osc_checksum_type()
7913 {
7914         # arugment 1: OST name, like OST0000
7915         ost=$1
7916         checksum_type=$(lctl get_param -n osc.*${ost}-osc-[^mM]*.checksum_type |
7917                         sed 's/.*\[\(.*\)\].*/\1/g')
7918         rc=$?
7919         [ $rc -ne 0 ] && error "failed to get checksum type of $ost, rc = $rc, output = $checksum_type"
7920         echo $checksum_type
7921 }
7922
7923 F77_TMP=$TMP/f77-temp
7924 F77SZ=8
7925 setup_f77() {
7926         dd if=/dev/urandom of=$F77_TMP bs=1M count=$F77SZ || \
7927                 error "error writing to $F77_TMP"
7928 }
7929
7930 test_77a() { # bug 10889
7931         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7932         $GSS && skip_env "could not run with gss"
7933
7934         [ ! -f $F77_TMP ] && setup_f77
7935         set_checksums 1
7936         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ || error "dd error"
7937         set_checksums 0
7938         rm -f $DIR/$tfile
7939 }
7940 run_test 77a "normal checksum read/write operation"
7941
7942 test_77b() { # bug 10889
7943         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7944         $GSS && skip_env "could not run with gss"
7945
7946         [ ! -f $F77_TMP ] && setup_f77
7947         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
7948         $LCTL set_param fail_loc=0x80000409
7949         set_checksums 1
7950
7951         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
7952                 error "dd error: $?"
7953         $LCTL set_param fail_loc=0
7954
7955         for algo in $CKSUM_TYPES; do
7956                 cancel_lru_locks osc
7957                 set_checksum_type $algo
7958                 #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
7959                 $LCTL set_param fail_loc=0x80000408
7960                 cmp $F77_TMP $DIR/$tfile || error "file compare failed"
7961                 $LCTL set_param fail_loc=0
7962         done
7963         set_checksums 0
7964         set_checksum_type $ORIG_CSUM_TYPE
7965         rm -f $DIR/$tfile
7966 }
7967 run_test 77b "checksum error on client write, read"
7968
7969 cleanup_77c() {
7970         trap 0
7971         set_checksums 0
7972         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=0
7973         $check_ost &&
7974                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=0
7975         [ -n "$osc_file_prefix" ] && rm -f ${osc_file_prefix}*
7976         $check_ost && [ -n "$ost_file_prefix" ] &&
7977                 do_facet ost1 rm -f ${ost_file_prefix}\*
7978 }
7979
7980 test_77c() {
7981         [ $PARALLEL == "yes" ] && skip "skip parallel run"
7982         $GSS && skip_env "could not run with gss"
7983         remote_ost_nodsh && skip "remote OST with nodsh"
7984
7985         local bad1
7986         local osc_file_prefix
7987         local osc_file
7988         local check_ost=false
7989         local ost_file_prefix
7990         local ost_file
7991         local orig_cksum
7992         local dump_cksum
7993         local fid
7994
7995         # ensure corruption will occur on first OSS/OST
7996         $LFS setstripe -i 0 $DIR/$tfile
7997
7998         [ ! -f $F77_TMP ] && setup_f77
7999         dd if=$F77_TMP of=$DIR/$tfile bs=1M count=$F77SZ conv=sync ||
8000                 error "dd write error: $?"
8001         fid=$($LFS path2fid $DIR/$tfile)
8002
8003         if [ $OST1_VERSION -ge $(version_code 2.9.57) ]
8004         then
8005                 check_ost=true
8006                 ost_file_prefix=$(do_facet ost1 $LCTL get_param -n debug_path)
8007                 ost_file_prefix=${ost_file_prefix}-checksum_dump-ost-\\${fid}
8008         else
8009                 echo "OSS do not support bulk pages dump upon error"
8010         fi
8011
8012         osc_file_prefix=$($LCTL get_param -n debug_path)
8013         osc_file_prefix=${osc_file_prefix}-checksum_dump-osc-\\${fid}
8014
8015         trap cleanup_77c EXIT
8016
8017         set_checksums 1
8018         # enable bulk pages dump upon error on Client
8019         $LCTL set_param osc.*osc-[^mM]*.checksum_dump=1
8020         # enable bulk pages dump upon error on OSS
8021         $check_ost &&
8022                 do_facet ost1 $LCTL set_param obdfilter.*-OST*.checksum_dump=1
8023
8024         # flush Client cache to allow next read to reach OSS
8025         cancel_lru_locks osc
8026
8027         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE       0x408
8028         $LCTL set_param fail_loc=0x80000408
8029         dd if=$DIR/$tfile of=/dev/null bs=1M || error "dd read error: $?"
8030         $LCTL set_param fail_loc=0
8031
8032         rm -f $DIR/$tfile
8033
8034         # check cksum dump on Client
8035         osc_file=$(ls ${osc_file_prefix}*)
8036         [ -n "$osc_file" ] || error "no checksum dump file on Client"
8037         # OBD_FAIL_OSC_CHECKSUM_RECEIVE corrupts with "bad1" at start of file
8038         bad1=$(dd if=$osc_file bs=1 count=4 2>/dev/null) || error "dd error: $?"
8039         [ $bad1 == "bad1" ] || error "unexpected corrupt pattern"
8040         orig_cksum=$(dd if=$F77_TMP bs=1 skip=4 count=1048572 2>/dev/null |
8041                      cksum)
8042         dump_cksum=$(dd if=$osc_file bs=1 skip=4 2>/dev/null | cksum)
8043         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8044                 error "dump content does not match on Client"
8045
8046         $check_ost || skip "No need to check cksum dump on OSS"
8047
8048         # check cksum dump on OSS
8049         ost_file=$(do_facet ost1 ls ${ost_file_prefix}\*)
8050         [ -n "$ost_file" ] || error "no checksum dump file on OSS"
8051         orig_cksum=$(dd if=$F77_TMP bs=1048576 count=1 2>/dev/null | cksum)
8052         dump_cksum=$(do_facet ost1 dd if=$ost_file 2>/dev/null \| cksum)
8053         [[ "$orig_cksum" == "$dump_cksum" ]] ||
8054                 error "dump content does not match on OSS"
8055
8056         cleanup_77c
8057 }
8058 run_test 77c "checksum error on client read with debug"
8059
8060 test_77d() { # bug 10889
8061         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8062         $GSS && skip_env "could not run with gss"
8063
8064         #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8065         $LCTL set_param fail_loc=0x80000409
8066         set_checksums 1
8067         $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8068                 error "direct write: rc=$?"
8069         $LCTL set_param fail_loc=0
8070         set_checksums 0
8071
8072         #define OBD_FAIL_OSC_CHECKSUM_RECEIVE    0x408
8073         $LCTL set_param fail_loc=0x80000408
8074         set_checksums 1
8075         cancel_lru_locks osc
8076         $DIRECTIO read $DIR/$tfile 0 $F77SZ $((1024 * 1024)) ||
8077                 error "direct read: rc=$?"
8078         $LCTL set_param fail_loc=0
8079         set_checksums 0
8080 }
8081 run_test 77d "checksum error on OST direct write, read"
8082
8083 test_77f() { # bug 10889
8084         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8085         $GSS && skip_env "could not run with gss"
8086
8087         set_checksums 1
8088         for algo in $CKSUM_TYPES; do
8089                 cancel_lru_locks osc
8090                 set_checksum_type $algo
8091                 #define OBD_FAIL_OSC_CHECKSUM_SEND       0x409
8092                 $LCTL set_param fail_loc=0x409
8093                 $DIRECTIO write $DIR/$tfile 0 $F77SZ $((1024 * 1024)) &&
8094                         error "direct write succeeded"
8095                 $LCTL set_param fail_loc=0
8096         done
8097         set_checksum_type $ORIG_CSUM_TYPE
8098         set_checksums 0
8099 }
8100 run_test 77f "repeat checksum error on write (expect error)"
8101
8102 test_77g() { # bug 10889
8103         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8104         $GSS && skip_env "could not run with gss"
8105         remote_ost_nodsh && skip "remote OST with nodsh"
8106
8107         [ ! -f $F77_TMP ] && setup_f77
8108
8109         local file=$DIR/$tfile
8110         stack_trap "rm -f $file" EXIT
8111
8112         $LFS setstripe -c 1 -i 0 $file
8113         #define OBD_FAIL_OST_CHECKSUM_RECEIVE       0x21a
8114         do_facet ost1 lctl set_param fail_loc=0x8000021a
8115         set_checksums 1
8116         dd if=$F77_TMP of=$file bs=1M count=$F77SZ ||
8117                 error "write error: rc=$?"
8118         do_facet ost1 lctl set_param fail_loc=0
8119         set_checksums 0
8120
8121         cancel_lru_locks osc
8122         #define OBD_FAIL_OST_CHECKSUM_SEND          0x21b
8123         do_facet ost1 lctl set_param fail_loc=0x8000021b
8124         set_checksums 1
8125         cmp $F77_TMP $file || error "file compare failed"
8126         do_facet ost1 lctl set_param fail_loc=0
8127         set_checksums 0
8128 }
8129 run_test 77g "checksum error on OST write, read"
8130
8131 test_77k() { # LU-10906
8132         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8133         $GSS && skip_env "could not run with gss"
8134
8135         local cksum_param="osc.$FSNAME*.checksums"
8136         local get_checksum="$LCTL get_param -n $cksum_param | head -n1"
8137         local checksum
8138         local i
8139
8140         [ "$ORIG_CSUM" ] || ORIG_CSUM=$(eval $get_checksum)
8141         stack_trap "wait_update $HOSTNAME '$get_checksum' $ORIG_CSUM" EXIT
8142         stack_trap "do_facet mgs $LCTL set_param -P $cksum_param=$ORIG_CSUM" \
8143                 EXIT
8144
8145         for i in 0 1; do
8146                 do_facet mgs $LCTL set_param -P $cksum_param=$i ||
8147                         error "failed to set checksum=$i on MGS"
8148                 wait_update $HOSTNAME "$get_checksum" $i
8149                 #remount
8150                 echo "remount client, checksum should be $i"
8151                 remount_client $MOUNT || error "failed to remount client"
8152                 checksum=$(eval $get_checksum)
8153                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8154         done
8155         # remove persistent param to avoid races with checksum mountopt below
8156         do_facet mgs $LCTL set_param -P -d $cksum_param ||
8157                 error "failed to delete checksum on MGS"
8158
8159         for opt in "checksum" "nochecksum"; do
8160                 #remount with mount option
8161                 echo "remount client with option $opt, checksum should be $i"
8162                 umount_client $MOUNT || error "failed to umount client"
8163                 mount_client $MOUNT "$MOUNT_OPTS,$opt" ||
8164                         error "failed to mount client with option '$opt'"
8165                 checksum=$(eval $get_checksum)
8166                 [ $checksum -eq $i ] || error "checksum($checksum) != $i"
8167                 i=$((i - 1))
8168         done
8169
8170         remount_client $MOUNT || error "failed to remount client"
8171 }
8172 run_test 77k "enable/disable checksum correctly"
8173
8174 test_77l() {
8175         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8176         $GSS && skip_env "could not run with gss"
8177
8178         set_checksums 1
8179         stack_trap "set_checksums $ORIG_CSUM" EXIT
8180         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
8181
8182         set_checksum_type invalid && error "unexpected success of invalid checksum type"
8183
8184         $LFS setstripe -c 1 -i 0 $DIR/$tfile
8185         for algo in $CKSUM_TYPES; do
8186                 set_checksum_type $algo || error "fail to set checksum type $algo"
8187                 osc_algo=$(get_osc_checksum_type OST0000)
8188                 [ "$osc_algo" != "$algo" ] && error "checksum type is $osc_algo after setting it to $algo"
8189
8190                 # no locks, no reqs to let the connection idle
8191                 cancel_lru_locks osc
8192                 lru_resize_disable osc
8193                 wait_osc_import_state client ost1 IDLE
8194
8195                 # ensure ost1 is connected
8196                 stat $DIR/$tfile >/dev/null || error "can't stat"
8197                 wait_osc_import_state client ost1 FULL
8198
8199                 osc_algo=$(get_osc_checksum_type OST0000)
8200                 [ "$osc_algo" != "$algo" ] && error "checksum type changed from $algo to $osc_algo after reconnection"
8201         done
8202         return 0
8203 }
8204 run_test 77l "preferred checksum type is remembered after reconnected"
8205
8206 [ "$ORIG_CSUM" ] && set_checksums $ORIG_CSUM || true
8207 rm -f $F77_TMP
8208 unset F77_TMP
8209
8210 cleanup_test_78() {
8211         trap 0
8212         rm -f $DIR/$tfile
8213 }
8214
8215 test_78() { # bug 10901
8216         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8217         remote_ost || skip_env "local OST"
8218
8219         NSEQ=5
8220         F78SIZE=$(($(awk '/MemFree:/ { print $2 }' /proc/meminfo) / 1024))
8221         echo "MemFree: $F78SIZE, Max file size: $MAXFREE"
8222         MEMTOTAL=$(($(awk '/MemTotal:/ { print $2 }' /proc/meminfo) / 1024))
8223         echo "MemTotal: $MEMTOTAL"
8224
8225         # reserve 256MB of memory for the kernel and other running processes,
8226         # and then take 1/2 of the remaining memory for the read/write buffers.
8227         if [ $MEMTOTAL -gt 512 ] ;then
8228                 MEMTOTAL=$(((MEMTOTAL - 256 ) / 2))
8229         else
8230                 # for those poor memory-starved high-end clusters...
8231                 MEMTOTAL=$((MEMTOTAL / 2))
8232         fi
8233         echo "Mem to use for directio: $MEMTOTAL"
8234
8235         [[ $F78SIZE -gt $MEMTOTAL ]] && F78SIZE=$MEMTOTAL
8236         [[ $F78SIZE -gt 512 ]] && F78SIZE=512
8237         [[ $F78SIZE -gt $((MAXFREE / 1024)) ]] && F78SIZE=$((MAXFREE / 1024))
8238         SMALLESTOST=$($LFS df $DIR | grep OST | awk '{ print $4 }' | sort -n |
8239                 head -n1)
8240         echo "Smallest OST: $SMALLESTOST"
8241         [[ $SMALLESTOST -lt 10240 ]] &&
8242                 skip "too small OSTSIZE, useless to run large O_DIRECT test"
8243
8244         trap cleanup_test_78 EXIT
8245
8246         [[ $F78SIZE -gt $((SMALLESTOST * $OSTCOUNT / 1024 - 80)) ]] &&
8247                 F78SIZE=$((SMALLESTOST * $OSTCOUNT / 1024 - 80))
8248
8249         [ "$SLOW" = "no" ] && NSEQ=1 && [ $F78SIZE -gt 32 ] && F78SIZE=32
8250         echo "File size: $F78SIZE"
8251         $LFS setstripe -c $OSTCOUNT $DIR/$tfile || error "setstripe failed"
8252         for i in $(seq 1 $NSEQ); do
8253                 FSIZE=$(($F78SIZE / ($NSEQ - $i + 1)))
8254                 echo directIO rdwr round $i of $NSEQ
8255                 $DIRECTIO rdwr $DIR/$tfile 0 $FSIZE 1048576||error "rdwr failed"
8256         done
8257
8258         cleanup_test_78
8259 }
8260 run_test 78 "handle large O_DIRECT writes correctly ============"
8261
8262 test_79() { # bug 12743
8263         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8264
8265         wait_delete_completed
8266
8267         BKTOTAL=$(calc_osc_kbytes kbytestotal)
8268         BKFREE=$(calc_osc_kbytes kbytesfree)
8269         BKAVAIL=$(calc_osc_kbytes kbytesavail)
8270
8271         STRING=`df -P $MOUNT | tail -n 1 | awk '{print $2","$3","$4}'`
8272         DFTOTAL=`echo $STRING | cut -d, -f1`
8273         DFUSED=`echo $STRING  | cut -d, -f2`
8274         DFAVAIL=`echo $STRING | cut -d, -f3`
8275         DFFREE=$(($DFTOTAL - $DFUSED))
8276
8277         ALLOWANCE=$((64 * $OSTCOUNT))
8278
8279         if [ $DFTOTAL -lt $(($BKTOTAL - $ALLOWANCE)) ] ||
8280            [ $DFTOTAL -gt $(($BKTOTAL + $ALLOWANCE)) ] ; then
8281                 error "df total($DFTOTAL) mismatch OST total($BKTOTAL)"
8282         fi
8283         if [ $DFFREE -lt $(($BKFREE - $ALLOWANCE)) ] ||
8284            [ $DFFREE -gt $(($BKFREE + $ALLOWANCE)) ] ; then
8285                 error "df free($DFFREE) mismatch OST free($BKFREE)"
8286         fi
8287         if [ $DFAVAIL -lt $(($BKAVAIL - $ALLOWANCE)) ] ||
8288            [ $DFAVAIL -gt $(($BKAVAIL + $ALLOWANCE)) ] ; then
8289                 error "df avail($DFAVAIL) mismatch OST avail($BKAVAIL)"
8290         fi
8291 }
8292 run_test 79 "df report consistency check ======================="
8293
8294 test_80() { # bug 10718
8295         remote_ost_nodsh && skip "remote OST with nodsh"
8296         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8297
8298         # relax strong synchronous semantics for slow backends like ZFS
8299         local soc="obdfilter.*.sync_on_lock_cancel"
8300         local soc_old=$(do_facet ost1 lctl get_param -n $soc | head -n1)
8301         local hosts=
8302         if [ "$soc_old" != "never" ] &&
8303                 [ "$ost1_FSTYPE" != "ldiskfs" ]; then
8304                         hosts=$(for host in $(seq -f "ost%g" 1 $OSTCOUNT); do
8305                                 facet_active_host $host; done | sort -u)
8306                         do_nodes $hosts lctl set_param $soc=never
8307         fi
8308
8309         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1M
8310         sync; sleep 1; sync
8311         local BEFORE=`date +%s`
8312         cancel_lru_locks osc
8313         local AFTER=`date +%s`
8314         local DIFF=$((AFTER-BEFORE))
8315         if [ $DIFF -gt 1 ] ; then
8316                 error "elapsed for 1M@1T = $DIFF"
8317         fi
8318
8319         [ -n "$hosts" ] && do_nodes $hosts lctl set_param $soc=$soc_old
8320
8321         rm -f $DIR/$tfile
8322 }
8323 run_test 80 "Page eviction is equally fast at high offsets too  ===="
8324
8325 test_81a() { # LU-456
8326         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8327         remote_ost_nodsh && skip "remote OST with nodsh"
8328
8329         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8330         # MUST OR with the OBD_FAIL_ONCE (0x80000000)
8331         do_facet ost1 lctl set_param fail_loc=0x80000228
8332
8333         # write should trigger a retry and success
8334         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8335         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8336         RC=$?
8337         if [ $RC -ne 0 ] ; then
8338                 error "write should success, but failed for $RC"
8339         fi
8340 }
8341 run_test 81a "OST should retry write when get -ENOSPC ==============="
8342
8343 test_81b() { # LU-456
8344         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8345         remote_ost_nodsh && skip "remote OST with nodsh"
8346
8347         # define OBD_FAIL_OST_MAPBLK_ENOSPC    0x228
8348         # Don't OR with the OBD_FAIL_ONCE (0x80000000)
8349         do_facet ost1 lctl set_param fail_loc=0x228
8350
8351         # write should retry several times and return -ENOSPC finally
8352         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8353         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
8354         RC=$?
8355         ENOSPC=28
8356         if [ $RC -ne $ENOSPC ] ; then
8357                 error "dd should fail for -ENOSPC, but succeed."
8358         fi
8359 }
8360 run_test 81b "OST should return -ENOSPC when retry still fails ======="
8361
8362 test_82() { # LU-1031
8363         dd if=/dev/zero of=$DIR/$tfile bs=1M count=10
8364         local gid1=14091995
8365         local gid2=16022000
8366
8367         multiop_bg_pause $DIR/$tfile OG${gid1}_g${gid1}c || return 1
8368         local MULTIPID1=$!
8369         multiop_bg_pause $DIR/$tfile O_G${gid2}r10g${gid2}c || return 2
8370         local MULTIPID2=$!
8371         kill -USR1 $MULTIPID2
8372         sleep 2
8373         if [[ `ps h -o comm -p $MULTIPID2` == "" ]]; then
8374                 error "First grouplock does not block second one"
8375         else
8376                 echo "Second grouplock blocks first one"
8377         fi
8378         kill -USR1 $MULTIPID1
8379         wait $MULTIPID1
8380         wait $MULTIPID2
8381 }
8382 run_test 82 "Basic grouplock test"
8383
8384 test_99() {
8385         [ -z "$(which cvs 2>/dev/null)" ] && skip_env "could not find cvs"
8386
8387         test_mkdir $DIR/$tdir.cvsroot
8388         chown $RUNAS_ID $DIR/$tdir.cvsroot
8389
8390         cd $TMP
8391         $RUNAS cvs -d $DIR/$tdir.cvsroot init || error "cvs init failed"
8392
8393         cd /etc/init.d
8394         # some versions of cvs import exit(1) when asked to import links or
8395         # files they can't read.  ignore those files.
8396         local toignore=$(find . -type l -printf '-I %f\n' -o \
8397                          ! -perm /4 -printf '-I %f\n')
8398         $RUNAS cvs -d $DIR/$tdir.cvsroot import -m "nomesg" $toignore \
8399                 $tdir.reposname vtag rtag
8400
8401         cd $DIR
8402         test_mkdir $DIR/$tdir.reposname
8403         chown $RUNAS_ID $DIR/$tdir.reposname
8404         $RUNAS cvs -d $DIR/$tdir.cvsroot co $tdir.reposname
8405
8406         cd $DIR/$tdir.reposname
8407         $RUNAS touch foo99
8408         $RUNAS cvs add -m 'addmsg' foo99
8409         $RUNAS cvs update
8410         $RUNAS cvs commit -m 'nomsg' foo99
8411         rm -fr $DIR/$tdir.cvsroot
8412 }
8413 run_test 99 "cvs strange file/directory operations"
8414
8415 test_100() {
8416         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8417         [[ "$NETTYPE" =~ tcp ]] ||
8418                 skip_env "TCP secure port test, not useful for NETTYPE=$NETTYPE"
8419         remote_ost_nodsh && skip "remote OST with nodsh"
8420         remote_mds_nodsh && skip "remote MDS with nodsh"
8421         remote_servers ||
8422                 skip "useless for local single node setup"
8423
8424         netstat -tna | ( rc=1; while read PROT SND RCV LOCAL REMOTE STAT; do
8425                 [ "$PROT" != "tcp" ] && continue
8426                 RPORT=$(echo $REMOTE | cut -d: -f2)
8427                 [ "$RPORT" != "$ACCEPTOR_PORT" ] && continue
8428
8429                 rc=0
8430                 LPORT=`echo $LOCAL | cut -d: -f2`
8431                 if [ $LPORT -ge 1024 ]; then
8432                         echo "bad: $PROT $SND $RCV $LOCAL $REMOTE $STAT"
8433                         netstat -tna
8434                         error_exit "local: $LPORT > 1024, remote: $RPORT"
8435                 fi
8436         done
8437         [ "$rc" = 0 ] || error_exit "privileged port not found" )
8438 }
8439 run_test 100 "check local port using privileged port ==========="
8440
8441 function get_named_value()
8442 {
8443     local tag
8444
8445     tag=$1
8446     while read ;do
8447         line=$REPLY
8448         case $line in
8449         $tag*)
8450             echo $line | sed "s/^$tag[ ]*//"
8451             break
8452             ;;
8453         esac
8454     done
8455 }
8456
8457 export CACHE_MAX=$($LCTL get_param -n llite.*.max_cached_mb |
8458                    awk '/^max_cached_mb/ { print $2 }')
8459
8460 cleanup_101a() {
8461         $LCTL set_param -n llite.*.max_cached_mb $CACHE_MAX
8462         trap 0
8463 }
8464
8465 test_101a() {
8466         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8467         [ $MDSCOUNT -ge 2 ] && skip_env "needs < 2 MDTs" #LU-4322
8468
8469         local s
8470         local discard
8471         local nreads=10000
8472         local cache_limit=32
8473
8474         $LCTL set_param -n osc.*-osc*.rpc_stats 0
8475         trap cleanup_101a EXIT
8476         $LCTL set_param -n llite.*.read_ahead_stats 0
8477         $LCTL set_param -n llite.*.max_cached_mb $cache_limit
8478
8479         #
8480         # randomly read 10000 of 64K chunks from file 3x 32MB in size
8481         #
8482         echo "nreads: $nreads file size: $((cache_limit * 3))MB"
8483         $READS -f $DIR/$tfile -s$((cache_limit * 3192 * 1024)) -b65536 -C -n$nreads -t 180
8484
8485         discard=0
8486         for s in $($LCTL get_param -n llite.*.read_ahead_stats |
8487                 get_named_value 'read but discarded' | cut -d" " -f1); do
8488                         discard=$(($discard + $s))
8489         done
8490         cleanup_101a
8491
8492         if [[ $(($discard * 10)) -gt $nreads ]]; then
8493                 $LCTL get_param osc.*-osc*.rpc_stats
8494                 $LCTL get_param llite.*.read_ahead_stats
8495                 error "too many ($discard) discarded pages"
8496         fi
8497         rm -f $DIR/$tfile || true
8498 }
8499 run_test 101a "check read-ahead for random reads"
8500
8501 setup_test101bc() {
8502         test_mkdir $DIR/$tdir
8503         local ssize=$1
8504         local FILE_LENGTH=$2
8505         STRIPE_OFFSET=0
8506
8507         local FILE_SIZE_MB=$((FILE_LENGTH / ssize))
8508
8509         local list=$(comma_list $(osts_nodes))
8510         set_osd_param $list '' read_cache_enable 0
8511         set_osd_param $list '' writethrough_cache_enable 0
8512
8513         trap cleanup_test101bc EXIT
8514         # prepare the read-ahead file
8515         $LFS setstripe -S $ssize -i $STRIPE_OFFSET -c $OSTCOUNT $DIR/$tfile
8516
8517         dd if=/dev/zero of=$DIR/$tfile bs=$ssize \
8518                                 count=$FILE_SIZE_MB 2> /dev/null
8519
8520 }
8521
8522 cleanup_test101bc() {
8523         trap 0
8524         rm -rf $DIR/$tdir
8525         rm -f $DIR/$tfile
8526
8527         local list=$(comma_list $(osts_nodes))
8528         set_osd_param $list '' read_cache_enable 1
8529         set_osd_param $list '' writethrough_cache_enable 1
8530 }
8531
8532 calc_total() {
8533         awk 'BEGIN{total=0}; {total+=$1}; END{print total}'
8534 }
8535
8536 ra_check_101() {
8537         local READ_SIZE=$1
8538         local STRIPE_SIZE=$2
8539         local FILE_LENGTH=$3
8540         local RA_INC=1048576
8541         local STRIDE_LENGTH=$((STRIPE_SIZE/READ_SIZE))
8542         local discard_limit=$((((STRIDE_LENGTH - 1)*3/(STRIDE_LENGTH*OSTCOUNT))* \
8543                              (STRIDE_LENGTH*OSTCOUNT - STRIDE_LENGTH)))
8544         DISCARD=$($LCTL get_param -n llite.*.read_ahead_stats |
8545                         get_named_value 'read but discarded' |
8546                         cut -d" " -f1 | calc_total)
8547         if [[ $DISCARD -gt $discard_limit ]]; then
8548                 $LCTL get_param llite.*.read_ahead_stats
8549                 error "Too many ($DISCARD) discarded pages with size (${READ_SIZE})"
8550         else
8551                 echo "Read-ahead success for size ${READ_SIZE}"
8552         fi
8553 }
8554
8555 test_101b() {
8556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8557         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8558
8559         local STRIPE_SIZE=1048576
8560         local STRIDE_SIZE=$((STRIPE_SIZE*OSTCOUNT))
8561
8562         if [ $SLOW == "yes" ]; then
8563                 local FILE_LENGTH=$((STRIDE_SIZE * 64))
8564         else
8565                 local FILE_LENGTH=$((STRIDE_SIZE * 8))
8566         fi
8567
8568         local ITERATION=$((FILE_LENGTH / STRIDE_SIZE))
8569
8570         # prepare the read-ahead file
8571         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8572         cancel_lru_locks osc
8573         for BIDX in 2 4 8 16 32 64 128 256
8574         do
8575                 local BSIZE=$((BIDX*4096))
8576                 local READ_COUNT=$((STRIPE_SIZE/BSIZE))
8577                 local STRIDE_LENGTH=$((STRIDE_SIZE/BSIZE))
8578                 local OFFSET=$((STRIPE_SIZE/BSIZE*(OSTCOUNT - 1)))
8579                 $LCTL set_param -n llite.*.read_ahead_stats 0
8580                 $READS -f $DIR/$tfile  -l $STRIDE_LENGTH -o $OFFSET \
8581                               -s $FILE_LENGTH -b $STRIPE_SIZE -a $READ_COUNT -n $ITERATION
8582                 cancel_lru_locks osc
8583                 ra_check_101 $BSIZE $STRIPE_SIZE $FILE_LENGTH
8584         done
8585         cleanup_test101bc
8586         true
8587 }
8588 run_test 101b "check stride-io mode read-ahead ================="
8589
8590 test_101c() {
8591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8592
8593         local STRIPE_SIZE=1048576
8594         local FILE_LENGTH=$((STRIPE_SIZE*100))
8595         local nreads=10000
8596         local rsize=65536
8597         local osc_rpc_stats
8598
8599         setup_test101bc $STRIPE_SIZE $FILE_LENGTH
8600
8601         cancel_lru_locks osc
8602         $LCTL set_param osc.*.rpc_stats 0
8603         $READS -f $DIR/$tfile -s$FILE_LENGTH -b$rsize -n$nreads -t 180
8604         $LCTL get_param osc.*.rpc_stats
8605         for osc_rpc_stats in $($LCTL get_param -N osc.*.rpc_stats); do
8606                 local stats=$($LCTL get_param -n $osc_rpc_stats)
8607                 local lines=$(echo "$stats" | awk 'END {print NR;}')
8608                 local size
8609
8610                 if [ $lines -le 20 ]; then
8611                         echo "continue debug"
8612                         continue
8613                 fi
8614                 for size in 1 2 4 8; do
8615                         local rpc=$(echo "$stats" |
8616                                     awk '($1 == "'$size':") {print $2; exit; }')
8617                         [ $rpc != 0 ] && ((size * PAGE_SIZE < rsize)) &&
8618                                 error "Small $((size*PAGE_SIZE)) read IO $rpc!"
8619                 done
8620                 echo "$osc_rpc_stats check passed!"
8621         done
8622         cleanup_test101bc
8623         true
8624 }
8625 run_test 101c "check stripe_size aligned read-ahead ================="
8626
8627 set_read_ahead() {
8628         $LCTL get_param -n llite.*.max_read_ahead_mb | head -n 1
8629         $LCTL set_param -n llite.*.max_read_ahead_mb $1 > /dev/null 2>&1
8630 }
8631
8632 test_101d() {
8633         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8634
8635         local file=$DIR/$tfile
8636         local sz_MB=${FILESIZE_101d:-500}
8637         local ra_MB=${READAHEAD_MB:-40}
8638
8639         local free_MB=$(($(df -P $DIR | tail -n 1 | awk '{ print $4 }') / 1024))
8640         [ $free_MB -lt $sz_MB ] &&
8641                 skip "Need free space ${sz_MB}M, have ${free_MB}M"
8642
8643         echo "Create test file $file size ${sz_MB}M, ${free_MB}M free"
8644         $LFS setstripe -c -1 $file || error "setstripe failed"
8645
8646         dd if=/dev/zero of=$file bs=1M count=$sz_MB || error "dd failed"
8647         echo Cancel LRU locks on lustre client to flush the client cache
8648         cancel_lru_locks osc
8649
8650         echo Disable read-ahead
8651         local old_READAHEAD=$(set_read_ahead 0)
8652
8653         echo Reading the test file $file with read-ahead disabled
8654         local raOFF=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8655
8656         echo Cancel LRU locks on lustre client to flush the client cache
8657         cancel_lru_locks osc
8658         echo Enable read-ahead with ${ra_MB}MB
8659         set_read_ahead $ra_MB
8660
8661         echo Reading the test file $file with read-ahead enabled
8662         local raON=$(do_and_time "dd if=$file of=/dev/null bs=1M count=$sz_MB")
8663
8664         echo "read-ahead disabled time read $raOFF"
8665         echo "read-ahead enabled  time read $raON"
8666
8667         set_read_ahead $old_READAHEAD
8668         rm -f $file
8669         wait_delete_completed
8670
8671         [ $raOFF -le 1 ] || [ $raON -lt $raOFF ] ||
8672                 error "readahead ${raON}s > no-readahead ${raOFF}s ${sz_MB}M"
8673 }
8674 run_test 101d "file read with and without read-ahead enabled"
8675
8676 test_101e() {
8677         [ $PARALLEL == "yes" ] && skip "skip parallel run"
8678
8679         local file=$DIR/$tfile
8680         local size_KB=500  #KB
8681         local count=100
8682         local bsize=1024
8683
8684         local free_KB=$(df -P $DIR | tail -n 1 | awk '{ print $4 }')
8685         local need_KB=$((count * size_KB))
8686         [[ $free_KB -le $need_KB ]] &&
8687                 skip_env "Need free space $need_KB, have $free_KB"
8688
8689         echo "Creating $count ${size_KB}K test files"
8690         for ((i = 0; i < $count; i++)); do
8691                 dd if=/dev/zero of=$file.$i bs=$bsize count=$size_KB 2>/dev/null
8692         done
8693
8694         echo "Cancel LRU locks on lustre client to flush the client cache"
8695         cancel_lru_locks $OSC
8696
8697         echo "Reset readahead stats"
8698         $LCTL set_param -n llite.*.read_ahead_stats 0
8699
8700         for ((i = 0; i < $count; i++)); do
8701                 dd if=$file.$i of=/dev/null bs=$bsize count=$size_KB 2>/dev/null
8702         done
8703
8704         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8705                      get_named_value 'misses' | cut -d" " -f1 | calc_total)
8706
8707         for ((i = 0; i < $count; i++)); do
8708                 rm -rf $file.$i 2>/dev/null
8709         done
8710
8711         #10000 means 20% reads are missing in readahead
8712         [[ $miss -lt 10000 ]] ||  error "misses too much for small reads"
8713 }
8714 run_test 101e "check read-ahead for small read(1k) for small files(500k)"
8715
8716 test_101f() {
8717         which iozone || skip_env "no iozone installed"
8718
8719         local old_debug=$($LCTL get_param debug)
8720         old_debug=${old_debug#*=}
8721         $LCTL set_param debug="reada mmap"
8722
8723         # create a test file
8724         iozone -i 0 -+n -r 1m -s 128m -w -f $DIR/$tfile > /dev/null 2>&1
8725
8726         echo Cancel LRU locks on lustre client to flush the client cache
8727         cancel_lru_locks osc
8728
8729         echo Reset readahead stats
8730         $LCTL set_param -n llite.*.read_ahead_stats 0
8731
8732         echo mmap read the file with small block size
8733         iozone -i 1 -u 1 -l 1 -+n -r 32k -s 128m -B -f $DIR/$tfile \
8734                 > /dev/null 2>&1
8735
8736         echo checking missing pages
8737         $LCTL get_param llite.*.read_ahead_stats
8738         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8739                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8740
8741         $LCTL set_param debug="$old_debug"
8742         [ $miss -lt 3 ] || error "misses too much pages ('$miss')!"
8743         rm -f $DIR/$tfile
8744 }
8745 run_test 101f "check mmap read performance"
8746
8747 test_101g_brw_size_test() {
8748         local mb=$1
8749         local pages=$((mb * 1048576 / PAGE_SIZE))
8750         local file=$DIR/$tfile
8751
8752         $LCTL set_param osc.*.max_pages_per_rpc=${mb}M ||
8753                 { error "unable to set max_pages_per_rpc=${mb}M"; return 1; }
8754         for mp in $($LCTL get_param -n osc.*.max_pages_per_rpc); do
8755                 [ $mp -ne $pages ] && error "max_pages_per_rpc $mp != $pages" &&
8756                         return 2
8757         done
8758
8759         stack_trap "rm -f $file" EXIT
8760         $LCTL set_param -n osc.*.rpc_stats=0
8761
8762         # 10 RPCs should be enough for the test
8763         local count=10
8764         dd if=/dev/zero of=$file bs=${mb}M count=$count ||
8765                 { error "dd write ${mb} MB blocks failed"; return 3; }
8766         cancel_lru_locks osc
8767         dd of=/dev/null if=$file bs=${mb}M count=$count ||
8768                 { error "dd write ${mb} MB blocks failed"; return 4; }
8769
8770         # calculate number of full-sized read and write RPCs
8771         rpcs=($($LCTL get_param -n 'osc.*.rpc_stats' |
8772                 sed -n '/pages per rpc/,/^$/p' |
8773                 awk '/'$pages':/ { reads += $2; writes += $6 }; \
8774                 END { print reads,writes }'))
8775         [ ${rpcs[0]} -ne $count ] && error "${rpcs[0]} != $count read RPCs" &&
8776                 return 5
8777         [ ${rpcs[1]} -ne $count ] && error "${rpcs[1]} != $count write RPCs" &&
8778                 return 6
8779
8780         return 0
8781 }
8782
8783 test_101g() {
8784         remote_ost_nodsh && skip "remote OST with nodsh"
8785
8786         local rpcs
8787         local osts=$(get_facets OST)
8788         local list=$(comma_list $(osts_nodes))
8789         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
8790         local brw_size="obdfilter.*.brw_size"
8791
8792         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8793
8794         local orig_mb=$(do_facet ost1 $LCTL get_param -n $brw_size | head -n 1)
8795
8796         if { [ $OST1_VERSION -ge $(version_code 2.8.52) ] ||
8797                 { [ $OST1_VERSION -ge $(version_code 2.7.17) ] &&
8798                   [ $OST1_VERSION -lt $(version_code 2.7.50) ]; }; } &&
8799            { [ $CLIENT_VERSION -ge $(version_code 2.8.52) ] ||
8800                 { [ $CLIENT_VERSION -ge $(version_code 2.7.17) ] &&
8801                   [ $CLIENT_VERSION -lt $(version_code 2.7.50) ]; }; }; then
8802
8803                 [ $OST1_VERSION -ge $(version_code 2.9.52) ] &&
8804                         suffix="M"
8805
8806                 if [[ $orig_mb -lt 16 ]]; then
8807                         save_lustre_params $osts "$brw_size" > $p
8808                         do_nodes $list $LCTL set_param -n $brw_size=16$suffix ||
8809                                 error "set 16MB RPC size failed"
8810
8811                         echo "remount client to enable new RPC size"
8812                         remount_client $MOUNT || error "remount_client failed"
8813                 fi
8814
8815                 test_101g_brw_size_test 16 || error "16MB RPC test failed"
8816                 # should be able to set brw_size=12, but no rpc_stats for that
8817                 test_101g_brw_size_test 8 || error "8MB RPC test failed"
8818         fi
8819
8820         test_101g_brw_size_test 4 || error "4MB RPC test failed"
8821
8822         if [[ $orig_mb -lt 16 ]]; then
8823                 restore_lustre_params < $p
8824                 remount_client $MOUNT || error "remount_client restore failed"
8825         fi
8826
8827         rm -f $p $DIR/$tfile
8828 }
8829 run_test 101g "Big bulk(4/16 MiB) readahead"
8830
8831 test_101h() {
8832         $LFS setstripe -i 0 -c 1 $DIR/$tfile
8833
8834         dd if=/dev/zero of=$DIR/$tfile bs=1M count=70 ||
8835                 error "dd 70M file failed"
8836         echo Cancel LRU locks on lustre client to flush the client cache
8837         cancel_lru_locks osc
8838
8839         echo "Reset readahead stats"
8840         $LCTL set_param -n llite.*.read_ahead_stats 0
8841
8842         echo "Read 10M of data but cross 64M bundary"
8843         dd if=$DIR/$tfile of=/dev/null bs=10M skip=6 count=1
8844         local miss=$($LCTL get_param -n llite.*.read_ahead_stats |
8845                         get_named_value 'misses' | cut -d" " -f1 | calc_total)
8846         [ $miss -eq 1 ] || error "expected miss 1 but got $miss"
8847         rm -f $p $DIR/$tfile
8848 }
8849 run_test 101h "Readahead should cover current read window"
8850
8851 setup_test102() {
8852         test_mkdir $DIR/$tdir
8853         chown $RUNAS_ID $DIR/$tdir
8854         STRIPE_SIZE=65536
8855         STRIPE_OFFSET=1
8856         STRIPE_COUNT=$OSTCOUNT
8857         [[ $OSTCOUNT -gt 4 ]] && STRIPE_COUNT=4
8858
8859         trap cleanup_test102 EXIT
8860         cd $DIR
8861         $1 $LFS setstripe -S $STRIPE_SIZE -i $STRIPE_OFFSET -c $STRIPE_COUNT $tdir
8862         cd $DIR/$tdir
8863         for num in 1 2 3 4; do
8864                 for count in $(seq 1 $STRIPE_COUNT); do
8865                         for idx in $(seq 0 $[$STRIPE_COUNT - 1]); do
8866                                 local size=`expr $STRIPE_SIZE \* $num`
8867                                 local file=file"$num-$idx-$count"
8868                                 $1 $LFS setstripe -S $size -i $idx -c $count $file
8869                         done
8870                 done
8871         done
8872
8873         cd $DIR
8874         $1 tar cf $TMP/f102.tar $tdir --xattrs
8875 }
8876
8877 cleanup_test102() {
8878         trap 0
8879         rm -f $TMP/f102.tar
8880         rm -rf $DIR/d0.sanity/d102
8881 }
8882
8883 test_102a() {
8884         [ "$UID" != 0 ] && skip "must run as root"
8885         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep xattr)" ] &&
8886                 skip_env "must have user_xattr"
8887
8888         [ -z "$(which setfattr 2>/dev/null)" ] &&
8889                 skip_env "could not find setfattr"
8890
8891         local testfile=$DIR/$tfile
8892
8893         touch $testfile
8894         echo "set/get xattr..."
8895         setfattr -n trusted.name1 -v value1 $testfile ||
8896                 error "setfattr -n trusted.name1=value1 $testfile failed"
8897         getfattr -n trusted.name1 $testfile 2> /dev/null |
8898           grep "trusted.name1=.value1" ||
8899                 error "$testfile missing trusted.name1=value1"
8900
8901         setfattr -n user.author1 -v author1 $testfile ||
8902                 error "setfattr -n user.author1=author1 $testfile failed"
8903         getfattr -n user.author1 $testfile 2> /dev/null |
8904           grep "user.author1=.author1" ||
8905                 error "$testfile missing trusted.author1=author1"
8906
8907         echo "listxattr..."
8908         setfattr -n trusted.name2 -v value2 $testfile ||
8909                 error "$testfile unable to set trusted.name2"
8910         setfattr -n trusted.name3 -v value3 $testfile ||
8911                 error "$testfile unable to set trusted.name3"
8912         [ $(getfattr -d -m "^trusted" $testfile 2> /dev/null |
8913             grep "trusted.name" | wc -l) -eq 3 ] ||
8914                 error "$testfile missing 3 trusted.name xattrs"
8915
8916         setfattr -n user.author2 -v author2 $testfile ||
8917                 error "$testfile unable to set user.author2"
8918         setfattr -n user.author3 -v author3 $testfile ||
8919                 error "$testfile unable to set user.author3"
8920         [ $(getfattr -d -m "^user" $testfile 2> /dev/null |
8921             grep "user.author" | wc -l) -eq 3 ] ||
8922                 error "$testfile missing 3 user.author xattrs"
8923
8924         echo "remove xattr..."
8925         setfattr -x trusted.name1 $testfile ||
8926                 error "$testfile error deleting trusted.name1"
8927         getfattr -d -m trusted $testfile 2> /dev/null | grep "trusted.name1" &&
8928                 error "$testfile did not delete trusted.name1 xattr"
8929
8930         setfattr -x user.author1 $testfile ||
8931                 error "$testfile error deleting user.author1"
8932         echo "set lustre special xattr ..."
8933         $LFS setstripe -c1 $testfile
8934         local lovea=$(getfattr -n "trusted.lov" -e hex $testfile |
8935                 awk -F "=" '/trusted.lov/ { print $2 }' )
8936         setfattr -n "trusted.lov" -v $lovea $testfile ||
8937                 error "$testfile doesn't ignore setting trusted.lov again"
8938         setfattr -n "trusted.lov" -v "invalid_value" $testfile &&
8939                 error "$testfile allow setting invalid trusted.lov"
8940         rm -f $testfile
8941 }
8942 run_test 102a "user xattr test =================================="
8943
8944 test_102b() {
8945         [ -z "$(which setfattr 2>/dev/null)" ] &&
8946                 skip_env "could not find setfattr"
8947         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8948
8949         # b10930: get/set/list trusted.lov xattr
8950         echo "get/set/list trusted.lov xattr ..."
8951         local testfile=$DIR/$tfile
8952         $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8953                 error "setstripe failed"
8954         local STRIPECOUNT=$($LFS getstripe -c $testfile) ||
8955                 error "getstripe failed"
8956         getfattr -d -m "^trusted" $testfile 2>/dev/null | grep "trusted.lov" ||
8957                 error "can't get trusted.lov from $testfile"
8958
8959         local testfile2=${testfile}2
8960         local value=$(getfattr -n trusted.lov $testfile 2>/dev/null |
8961                         grep "trusted.lov" | sed -e 's/[^=]\+=//')
8962
8963         $MCREATE $testfile2
8964         setfattr -n trusted.lov -v $value $testfile2
8965         local stripe_size=$($LFS getstripe -S $testfile2)
8966         local stripe_count=$($LFS getstripe -c $testfile2)
8967         [[ $stripe_size -eq 65536 ]] ||
8968                 error "stripe size $stripe_size != 65536"
8969         [[ $stripe_count -eq $STRIPECOUNT ]] ||
8970                 error "stripe count $stripe_count != $STRIPECOUNT"
8971         rm -f $DIR/$tfile
8972 }
8973 run_test 102b "getfattr/setfattr for trusted.lov EAs ============"
8974
8975 test_102c() {
8976         [ -z "$(which setfattr 2>/dev/null)" ] &&
8977                 skip_env "could not find setfattr"
8978         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
8979
8980         # b10930: get/set/list lustre.lov xattr
8981         echo "get/set/list lustre.lov xattr ..."
8982         test_mkdir $DIR/$tdir
8983         chown $RUNAS_ID $DIR/$tdir
8984         local testfile=$DIR/$tdir/$tfile
8985         $RUNAS $LFS setstripe -S 65536 -i 1 -c $OSTCOUNT $testfile ||
8986                 error "setstripe failed"
8987         local STRIPECOUNT=$($RUNAS $LFS getstripe -c $testfile) ||
8988                 error "getstripe failed"
8989         $RUNAS getfattr -d -m "^lustre" $testfile 2> /dev/null | \
8990         grep "lustre.lov" || error "can't get lustre.lov from $testfile"
8991
8992         local testfile2=${testfile}2
8993         local value=`getfattr -n lustre.lov $testfile 2> /dev/null | \
8994                      grep "lustre.lov" |sed -e 's/[^=]\+=//'  `
8995
8996         $RUNAS $MCREATE $testfile2
8997         $RUNAS setfattr -n lustre.lov -v $value $testfile2
8998         local stripe_size=$($RUNAS $LFS getstripe -S $testfile2)
8999         local stripe_count=$($RUNAS $LFS getstripe -c $testfile2)
9000         [ $stripe_size -eq 65536 ] || error "stripe size $stripe_size != 65536"
9001         [ $stripe_count -eq $STRIPECOUNT ] ||
9002                 error "stripe count $stripe_count != $STRIPECOUNT"
9003 }
9004 run_test 102c "non-root getfattr/setfattr for lustre.lov EAs ==========="
9005
9006 compare_stripe_info1() {
9007         local stripe_index_all_zero=true
9008
9009         for num in 1 2 3 4; do
9010                 for count in $(seq 1 $STRIPE_COUNT); do
9011                         for offset in $(seq 0 $[$STRIPE_COUNT - 1]); do
9012                                 local size=$((STRIPE_SIZE * num))
9013                                 local file=file"$num-$offset-$count"
9014                                 stripe_size=$($LFS getstripe -S $PWD/$file)
9015                                 [[ $stripe_size -ne $size ]] &&
9016                                     error "$file: size $stripe_size != $size"
9017                                 stripe_count=$($LFS getstripe -c $PWD/$file)
9018                                 # allow fewer stripes to be created, ORI-601
9019                                 [[ $stripe_count -lt $(((3 * count + 3) / 4)) ]] &&
9020                                     error "$file: count $stripe_count != $count"
9021                                 stripe_index=$($LFS getstripe -i $PWD/$file)
9022                                 [[ $stripe_index -ne 0 ]] &&
9023                                         stripe_index_all_zero=false
9024                         done
9025                 done
9026         done
9027         $stripe_index_all_zero &&
9028                 error "all files are being extracted starting from OST index 0"
9029         return 0
9030 }
9031
9032 have_xattrs_include() {
9033         tar --help | grep -q xattrs-include &&
9034                 echo --xattrs-include="lustre.*"
9035 }
9036
9037 test_102d() {
9038         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9039         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9040
9041         XINC=$(have_xattrs_include)
9042         setup_test102
9043         tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9044         cd $DIR/$tdir/$tdir
9045         compare_stripe_info1
9046 }
9047 run_test 102d "tar restore stripe info from tarfile,not keep osts"
9048
9049 test_102f() {
9050         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9051         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9052
9053         XINC=$(have_xattrs_include)
9054         setup_test102
9055         test_mkdir $DIR/$tdir.restore
9056         cd $DIR
9057         tar cf - --xattrs $tdir | tar xf - \
9058                 -C $DIR/$tdir.restore --xattrs $XINC
9059         cd $DIR/$tdir.restore/$tdir
9060         compare_stripe_info1
9061 }
9062 run_test 102f "tar copy files, not keep osts"
9063
9064 grow_xattr() {
9065         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep xattr)" ] &&
9066                 skip "must have user_xattr"
9067         [ -z "$(which setfattr 2>/dev/null)" ] &&
9068                 skip_env "could not find setfattr"
9069         [ -z "$(which getfattr 2>/dev/null)" ] &&
9070                 skip_env "could not find getfattr"
9071
9072         local xsize=${1:-1024}  # in bytes
9073         local file=$DIR/$tfile
9074         local value="$(generate_string $xsize)"
9075         local xbig=trusted.big
9076         local toobig=$2
9077
9078         touch $file
9079         log "save $xbig on $file"
9080         if [ -z "$toobig" ]
9081         then
9082                 setfattr -n $xbig -v $value $file ||
9083                         error "saving $xbig on $file failed"
9084         else
9085                 setfattr -n $xbig -v $value $file &&
9086                         error "saving $xbig on $file succeeded"
9087                 return 0
9088         fi
9089
9090         local orig=$(get_xattr_value $xbig $file)
9091         [[ "$orig" != "$value" ]] && error "$xbig different after saving $xbig"
9092
9093         local xsml=trusted.sml
9094         log "save $xsml on $file"
9095         setfattr -n $xsml -v val $file || error "saving $xsml on $file failed"
9096
9097         local new=$(get_xattr_value $xbig $file)
9098         [[ "$new" != "$orig" ]] && error "$xbig different after saving $xsml"
9099
9100         log "grow $xsml on $file"
9101         setfattr -n $xsml -v "$value" $file ||
9102                 error "growing $xsml on $file failed"
9103
9104         new=$(get_xattr_value $xbig $file)
9105         [[ "$new" != "$orig" ]] && error "$xbig different after growing $xsml"
9106         log "$xbig still valid after growing $xsml"
9107
9108         rm -f $file
9109 }
9110
9111 test_102h() { # bug 15777
9112         grow_xattr 1024
9113 }
9114 run_test 102h "grow xattr from inside inode to external block"
9115
9116 test_102ha() {
9117         large_xattr_enabled || skip_env "ea_inode feature disabled"
9118
9119         echo "setting xattr of max xattr size: $(max_xattr_size)"
9120         grow_xattr $(max_xattr_size)
9121
9122         echo "setting xattr of > max xattr size: $(max_xattr_size) + 10"
9123         echo "This should fail:"
9124         grow_xattr $(($(max_xattr_size) + 10)) 1
9125 }
9126 run_test 102ha "grow xattr from inside inode to external inode"
9127
9128 test_102i() { # bug 17038
9129         [ -z "$(which getfattr 2>/dev/null)" ] &&
9130                 skip "could not find getfattr"
9131
9132         touch $DIR/$tfile
9133         ln -s $DIR/$tfile $DIR/${tfile}link
9134         getfattr -n trusted.lov $DIR/$tfile ||
9135                 error "lgetxattr on $DIR/$tfile failed"
9136         getfattr -h -n trusted.lov $DIR/${tfile}link 2>&1 |
9137                 grep -i "no such attr" ||
9138                 error "error for lgetxattr on $DIR/${tfile}link is not ENODATA"
9139         rm -f $DIR/$tfile $DIR/${tfile}link
9140 }
9141 run_test 102i "lgetxattr test on symbolic link ============"
9142
9143 test_102j() {
9144         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9145         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9146
9147         XINC=$(have_xattrs_include)
9148         setup_test102 "$RUNAS"
9149         chown $RUNAS_ID $DIR/$tdir
9150         $RUNAS tar xf $TMP/f102.tar -C $DIR/$tdir --xattrs $XINC
9151         cd $DIR/$tdir/$tdir
9152         compare_stripe_info1 "$RUNAS"
9153 }
9154 run_test 102j "non-root tar restore stripe info from tarfile, not keep osts ==="
9155
9156 test_102k() {
9157         [ -z "$(which setfattr 2>/dev/null)" ] &&
9158                 skip "could not find setfattr"
9159
9160         touch $DIR/$tfile
9161         # b22187 just check that does not crash for regular file.
9162         setfattr -n trusted.lov $DIR/$tfile
9163         # b22187 'setfattr -n trusted.lov' should remove LOV EA for directories
9164         local test_kdir=$DIR/$tdir
9165         test_mkdir $test_kdir
9166         local default_size=$($LFS getstripe -S $test_kdir)
9167         local default_count=$($LFS getstripe -c $test_kdir)
9168         local default_offset=$($LFS getstripe -i $test_kdir)
9169         $LFS setstripe -S 65536 -i 0 -c $OSTCOUNT $test_kdir ||
9170                 error 'dir setstripe failed'
9171         setfattr -n trusted.lov $test_kdir
9172         local stripe_size=$($LFS getstripe -S $test_kdir)
9173         local stripe_count=$($LFS getstripe -c $test_kdir)
9174         local stripe_offset=$($LFS getstripe -i $test_kdir)
9175         [ $stripe_size -eq $default_size ] ||
9176                 error "stripe size $stripe_size != $default_size"
9177         [ $stripe_count -eq $default_count ] ||
9178                 error "stripe count $stripe_count != $default_count"
9179         [ $stripe_offset -eq $default_offset ] ||
9180                 error "stripe offset $stripe_offset != $default_offset"
9181         rm -rf $DIR/$tfile $test_kdir
9182 }
9183 run_test 102k "setfattr without parameter of value shouldn't cause a crash"
9184
9185 test_102l() {
9186         [ -z "$(which getfattr 2>/dev/null)" ] &&
9187                 skip "could not find getfattr"
9188
9189         # LU-532 trusted. xattr is invisible to non-root
9190         local testfile=$DIR/$tfile
9191
9192         touch $testfile
9193
9194         echo "listxattr as user..."
9195         chown $RUNAS_ID $testfile
9196         $RUNAS getfattr -d -m '.*' $testfile 2>&1 |
9197             grep -q "trusted" &&
9198                 error "$testfile trusted xattrs are user visible"
9199
9200         return 0;
9201 }
9202 run_test 102l "listxattr size test =================================="
9203
9204 test_102m() { # LU-3403 llite: error of listxattr when buffer is small
9205         local path=$DIR/$tfile
9206         touch $path
9207
9208         listxattr_size_check $path || error "listattr_size_check $path failed"
9209 }
9210 run_test 102m "Ensure listxattr fails on small bufffer ========"
9211
9212 cleanup_test102
9213
9214 getxattr() { # getxattr path name
9215         # Return the base64 encoding of the value of xattr name on path.
9216         local path=$1
9217         local name=$2
9218
9219         # # getfattr --absolute-names --encoding=base64 --name=trusted.lov $path
9220         # file: $path
9221         # trusted.lov=0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9222         #
9223         # We print just 0s0AvRCwEAAAAGAAAAAAAAAAAEAAACAAAAAAAQAAEAA...AAAAAAAAA=
9224
9225         getfattr --absolute-names --encoding=base64 --name=$name $path |
9226                 awk -F= -v name=$name '$1 == name {
9227                         print substr($0, index($0, "=") + 1);
9228         }'
9229 }
9230
9231 test_102n() { # LU-4101 mdt: protect internal xattrs
9232         [ -z "$(which setfattr 2>/dev/null)" ] &&
9233                 skip "could not find setfattr"
9234         if [ $MDS1_VERSION -lt $(version_code 2.5.50) ]
9235         then
9236                 skip "MDT < 2.5.50 allows setxattr on internal trusted xattrs"
9237         fi
9238
9239         local file0=$DIR/$tfile.0
9240         local file1=$DIR/$tfile.1
9241         local xattr0=$TMP/$tfile.0
9242         local xattr1=$TMP/$tfile.1
9243         local namelist="lov lma lmv link fid version som hsm"
9244         local name
9245         local value
9246
9247         rm -rf $file0 $file1 $xattr0 $xattr1
9248         touch $file0 $file1
9249
9250         # Get 'before' xattrs of $file1.
9251         getfattr --absolute-names --dump --match=- $file1 > $xattr0
9252
9253         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
9254                 namelist+=" lfsck_namespace"
9255         for name in $namelist; do
9256                 # Try to copy xattr from $file0 to $file1.
9257                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9258
9259                 setfattr --name=trusted.$name --value="$value" $file1 ||
9260                         error "setxattr 'trusted.$name' failed"
9261
9262                 # Try to set a garbage xattr.
9263                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9264
9265                 if [[ x$name == "xlov" ]]; then
9266                         setfattr --name=trusted.lov --value="$value" $file1 &&
9267                         error "setxattr invalid 'trusted.lov' success"
9268                 else
9269                         setfattr --name=trusted.$name --value="$value" $file1 ||
9270                                 error "setxattr invalid 'trusted.$name' failed"
9271                 fi
9272
9273                 # Try to remove the xattr from $file1. We don't care if this
9274                 # appears to succeed or fail, we just don't want there to be
9275                 # any changes or crashes.
9276                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9277         done
9278
9279         if [ $MDS1_VERSION -gt $(version_code 2.6.50) ]
9280         then
9281                 name="lfsck_ns"
9282                 # Try to copy xattr from $file0 to $file1.
9283                 value=$(getxattr $file0 trusted.$name 2> /dev/null)
9284
9285                 setfattr --name=trusted.$name --value="$value" $file1 ||
9286                         error "setxattr 'trusted.$name' failed"
9287
9288                 # Try to set a garbage xattr.
9289                 value=0sVGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIGl0c2VsZi4=
9290
9291                 setfattr --name=trusted.$name --value="$value" $file1 ||
9292                         error "setxattr 'trusted.$name' failed"
9293
9294                 # Try to remove the xattr from $file1. We don't care if this
9295                 # appears to succeed or fail, we just don't want there to be
9296                 # any changes or crashes.
9297                 setfattr --remove=$trusted.$name $file1 2> /dev/null
9298         fi
9299
9300         # Get 'after' xattrs of file1.
9301         getfattr --absolute-names --dump --match=- $file1 > $xattr1
9302
9303         if ! diff $xattr0 $xattr1; then
9304                 error "before and after xattrs of '$file1' differ"
9305         fi
9306
9307         rm -rf $file0 $file1 $xattr0 $xattr1
9308
9309         return 0
9310 }
9311 run_test 102n "silently ignore setxattr on internal trusted xattrs"
9312
9313 test_102p() { # LU-4703 setxattr did not check ownership
9314         [ $MDS1_VERSION -lt $(version_code 2.5.56) ] &&
9315                 skip "MDS needs to be at least 2.5.56"
9316
9317         local testfile=$DIR/$tfile
9318
9319         touch $testfile
9320
9321         echo "setfacl as user..."
9322         $RUNAS setfacl -m "u:$RUNAS_ID:rwx" $testfile
9323         [ $? -ne 0 ] || error "setfacl by $RUNAS_ID was allowed on $testfile"
9324
9325         echo "setfattr as user..."
9326         setfacl -m "u:$RUNAS_ID:---" $testfile
9327         $RUNAS setfattr -x system.posix_acl_access $testfile
9328         [ $? -ne 0 ] || error "setfattr by $RUNAS_ID was allowed on $testfile"
9329 }
9330 run_test 102p "check setxattr(2) correctly fails without permission"
9331
9332 test_102q() {
9333         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] &&
9334                 skip "MDS needs to be at least 2.6.92"
9335
9336         orphan_linkea_check $DIR/$tfile || error "orphan_linkea_check"
9337 }
9338 run_test 102q "flistxattr should not return trusted.link EAs for orphans"
9339
9340 test_102r() {
9341         [ $MDS1_VERSION -lt $(version_code 2.6.93) ] &&
9342                 skip "MDS needs to be at least 2.6.93"
9343
9344         touch $DIR/$tfile || error "touch"
9345         setfattr -n user.$(basename $tfile) $DIR/$tfile || error "setfattr"
9346         getfattr -n user.$(basename $tfile) $DIR/$tfile || error "getfattr"
9347         rm $DIR/$tfile || error "rm"
9348
9349         #normal directory
9350         mkdir -p $DIR/$tdir || error "mkdir"
9351         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9352         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9353         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9354                 error "$testfile error deleting user.author1"
9355         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9356                 grep "user.$(basename $tdir)" &&
9357                 error "$tdir did not delete user.$(basename $tdir)"
9358         rmdir $DIR/$tdir || error "rmdir"
9359
9360         #striped directory
9361         test_mkdir $DIR/$tdir
9362         setfattr -n user.$(basename $tdir) $DIR/$tdir || error "setfattr dir"
9363         getfattr -n user.$(basename $tdir) $DIR/$tdir || error "getfattr dir"
9364         setfattr -x user.$(basename $tdir) $DIR/$tdir ||
9365                 error "$testfile error deleting user.author1"
9366         getfattr -d -m user.$(basename $tdir) 2> /dev/null |
9367                 grep "user.$(basename $tdir)" &&
9368                 error "$tdir did not delete user.$(basename $tdir)"
9369         rmdir $DIR/$tdir || error "rm striped dir"
9370 }
9371 run_test 102r "set EAs with empty values"
9372
9373 test_102s() {
9374         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9375                 skip "MDS needs to be at least 2.11.52"
9376
9377         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9378
9379         save_lustre_params client "llite.*.xattr_cache" > $save
9380
9381         for cache in 0 1; do
9382                 lctl set_param llite.*.xattr_cache=$cache
9383
9384                 rm -f $DIR/$tfile
9385                 touch $DIR/$tfile || error "touch"
9386                 for prefix in lustre security system trusted user; do
9387                         # Note getxattr() may fail with 'Operation not
9388                         # supported' or 'No such attribute' depending
9389                         # on prefix and cache.
9390                         getfattr -n $prefix.n102s $DIR/$tfile &&
9391                                 error "getxattr '$prefix.n102s' should fail (cache = $cache)"
9392                 done
9393         done
9394
9395         restore_lustre_params < $save
9396 }
9397 run_test 102s "getting nonexistent xattrs should fail"
9398
9399 test_102t() {
9400         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
9401                 skip "MDS needs to be at least 2.11.52"
9402
9403         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
9404
9405         save_lustre_params client "llite.*.xattr_cache" > $save
9406
9407         for cache in 0 1; do
9408                 lctl set_param llite.*.xattr_cache=$cache
9409
9410                 for buf_size in 0 256; do
9411                         rm -f $DIR/$tfile
9412                         touch $DIR/$tfile || error "touch"
9413                         setfattr -n user.multiop $DIR/$tfile
9414                         $MULTIOP $DIR/$tfile oa$buf_size ||
9415                                 error "cannot get zero length xattr value (buf_size = $buf_size)"
9416                 done
9417         done
9418
9419         restore_lustre_params < $save
9420 }
9421 run_test 102t "zero length xattr values handled correctly"
9422
9423 run_acl_subtest()
9424 {
9425     $LUSTRE/tests/acl/run $LUSTRE/tests/acl/$1.test
9426     return $?
9427 }
9428
9429 test_103a() {
9430         [ "$UID" != 0 ] && skip "must run as root"
9431         $GSS && skip_env "could not run under gss"
9432         [ -z "$(lctl get_param -n mdc.*-mdc-*.connect_flags | grep acl)" ] &&
9433                 skip_env "must have acl enabled"
9434         [ -z "$(which setfacl 2>/dev/null)" ] &&
9435                 skip_env "could not find setfacl"
9436         remote_mds_nodsh && skip "remote MDS with nodsh"
9437
9438         gpasswd -a daemon bin                           # LU-5641
9439         do_facet $SINGLEMDS gpasswd -a daemon bin       # LU-5641
9440
9441         declare -a identity_old
9442
9443         for num in $(seq $MDSCOUNT); do
9444                 switch_identity $num true || identity_old[$num]=$?
9445         done
9446
9447         SAVE_UMASK=$(umask)
9448         umask 0022
9449         mkdir -p $DIR/$tdir
9450         cd $DIR/$tdir
9451
9452         echo "performing cp ..."
9453         run_acl_subtest cp || error "run_acl_subtest cp failed"
9454         echo "performing getfacl-noacl..."
9455         run_acl_subtest getfacl-noacl || error "getfacl-noacl test failed"
9456         echo "performing misc..."
9457         run_acl_subtest misc || error  "misc test failed"
9458         echo "performing permissions..."
9459         run_acl_subtest permissions || error "permissions failed"
9460         # LU-1482 mdd: Setting xattr are properly checked with and without ACLs
9461         if [ $MDS1_VERSION -gt $(version_code 2.8.55) ] ||
9462                 { [ $MDS1_VERSION -lt $(version_code 2.6) ] &&
9463                         [ $MDS1_VERSION -ge $(version_code 2.5.29) ]; }
9464         then
9465                 echo "performing permissions xattr..."
9466                 run_acl_subtest permissions_xattr ||
9467                         error "permissions_xattr failed"
9468         fi
9469         echo "performing setfacl..."
9470         run_acl_subtest setfacl || error  "setfacl test failed"
9471
9472         # inheritance test got from HP
9473         echo "performing inheritance..."
9474         cp $LUSTRE/tests/acl/make-tree . || error "cannot copy make-tree"
9475         chmod +x make-tree || error "chmod +x failed"
9476         run_acl_subtest inheritance || error "inheritance test failed"
9477         rm -f make-tree
9478
9479         echo "LU-974 ignore umask when acl is enabled..."
9480         run_acl_subtest 974 || error "LU-974 umask test failed"
9481         if [ $MDSCOUNT -ge 2 ]; then
9482                 run_acl_subtest 974_remote ||
9483                         error "LU-974 umask test failed under remote dir"
9484         fi
9485
9486         echo "LU-2561 newly created file is same size as directory..."
9487         if [ "$mds1_FSTYPE" != "zfs" ]; then
9488                 run_acl_subtest 2561 || error "LU-2561 test failed"
9489         else
9490                 run_acl_subtest 2561_zfs || error "LU-2561 zfs test failed"
9491         fi
9492
9493         run_acl_subtest 4924 || error "LU-4924 test failed"
9494
9495         cd $SAVE_PWD
9496         umask $SAVE_UMASK
9497
9498         for num in $(seq $MDSCOUNT); do
9499                 if [ "${identity_old[$num]}" = 1 ]; then
9500                         switch_identity $num false || identity_old[$num]=$?
9501                 fi
9502         done
9503 }
9504 run_test 103a "acl test"
9505
9506 test_103b() {
9507         declare -a pids
9508         local U
9509
9510         for U in {0..511}; do
9511                 {
9512                 local O=$(printf "%04o" $U)
9513
9514                 umask $(printf "%04o" $((511 ^ $O)))
9515                 $LFS setstripe -c 1 $DIR/$tfile.s$O
9516                 local S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.s$O))
9517
9518                 (( $S == ($O & 0666) )) ||
9519                         error "lfs setstripe $DIR/$tfile.s$O '$S' != '$O'"
9520
9521                 $LFS setstripe -E16M -c 1 -E1G -S4M $DIR/$tfile.p$O
9522                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.p$O))
9523                 (( $S == ($O & 0666) )) ||
9524                         error "lfs setstripe -E $DIR/$tfile.p$O '$S' != '$O'"
9525
9526                 $LFS setstripe -N2 -c 1 $DIR/$tfile.m$O
9527                 S=$(printf "%04o" 0$(stat -c%a $DIR/$tfile.m$O))
9528                 (( $S == ($O & 0666) )) ||
9529                         error "lfs setstripe -N2 $DIR/$tfile.m$O '$S' != '$O'"
9530                 rm -f $DIR/$tfile.[smp]$0
9531                 } &
9532                 local pid=$!
9533
9534                 # limit the concurrently running threads to 64. LU-11878
9535                 local idx=$((U % 64))
9536                 [ -z "${pids[idx]}" ] || wait ${pids[idx]}
9537                 pids[idx]=$pid
9538         done
9539         wait
9540 }
9541 run_test 103b "umask lfs setstripe"
9542
9543 test_103c() {
9544         mkdir -p $DIR/$tdir
9545         cp -rp $DIR/$tdir $DIR/$tdir.bak
9546
9547         [ -n "$(getfattr -d -m. $DIR/$tdir | grep posix_acl_default)" ] &&
9548                 error "$DIR/$tdir shouldn't contain default ACL"
9549         [ -n "$(getfattr -d -m. $DIR/$tdir.bak | grep posix_acl_default)" ] &&
9550                 error "$DIR/$tdir.bak shouldn't contain default ACL"
9551         true
9552 }
9553 run_test 103c "'cp -rp' won't set empty acl"
9554
9555 test_104a() {
9556         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9557
9558         touch $DIR/$tfile
9559         lfs df || error "lfs df failed"
9560         lfs df -ih || error "lfs df -ih failed"
9561         lfs df -h $DIR || error "lfs df -h $DIR failed"
9562         lfs df -i $DIR || error "lfs df -i $DIR failed"
9563         lfs df $DIR/$tfile || error "lfs df $DIR/$tfile failed"
9564         lfs df -ih $DIR/$tfile || error "lfs df -ih $DIR/$tfile failed"
9565
9566         local OSC=$(lctl dl | grep OST0000-osc-[^M] | awk '{ print $4 }')
9567         lctl --device %$OSC deactivate
9568         lfs df || error "lfs df with deactivated OSC failed"
9569         lctl --device %$OSC activate
9570         # wait the osc back to normal
9571         wait_osc_import_ready client ost
9572
9573         lfs df || error "lfs df with reactivated OSC failed"
9574         rm -f $DIR/$tfile
9575 }
9576 run_test 104a "lfs df [-ih] [path] test ========================="
9577
9578 test_104b() {
9579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9580         [ $RUNAS_ID -eq $UID ] &&
9581                 skip_env "RUNAS_ID = UID = $UID -- skipping"
9582
9583         denied_cnt=$(($($RUNAS $LFS check servers 2>&1 |
9584                         grep "Permission denied" | wc -l)))
9585         if [ $denied_cnt -ne 0 ]; then
9586                 error "lfs check servers test failed"
9587         fi
9588 }
9589 run_test 104b "$RUNAS lfs check servers test ===================="
9590
9591 test_105a() {
9592         # doesn't work on 2.4 kernels
9593         touch $DIR/$tfile
9594         if $(flock_is_enabled); then
9595                 flocks_test 1 on -f $DIR/$tfile || error "fail flock on"
9596         else
9597                 flocks_test 1 off -f $DIR/$tfile || error "fail flock off"
9598         fi
9599         rm -f $DIR/$tfile
9600 }
9601 run_test 105a "flock when mounted without -o flock test ========"
9602
9603 test_105b() {
9604         touch $DIR/$tfile
9605         if $(flock_is_enabled); then
9606                 flocks_test 1 on -c $DIR/$tfile || error "fail flock on"
9607         else
9608                 flocks_test 1 off -c $DIR/$tfile || error "fail flock off"
9609         fi
9610         rm -f $DIR/$tfile
9611 }
9612 run_test 105b "fcntl when mounted without -o flock test ========"
9613
9614 test_105c() {
9615         touch $DIR/$tfile
9616         if $(flock_is_enabled); then
9617                 flocks_test 1 on -l $DIR/$tfile || error "fail flock on"
9618         else
9619                 flocks_test 1 off -l $DIR/$tfile || error "fail flock off"
9620         fi
9621         rm -f $DIR/$tfile
9622 }
9623 run_test 105c "lockf when mounted without -o flock test"
9624
9625 test_105d() { # bug 15924
9626         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9627
9628         test_mkdir $DIR/$tdir
9629         flock_is_enabled || skip_env "mount w/o flock enabled"
9630         #define OBD_FAIL_LDLM_CP_CB_WAIT  0x315
9631         $LCTL set_param fail_loc=0x80000315
9632         flocks_test 2 $DIR/$tdir
9633 }
9634 run_test 105d "flock race (should not freeze) ========"
9635
9636 test_105e() { # bug 22660 && 22040
9637         flock_is_enabled || skip_env "mount w/o flock enabled"
9638
9639         touch $DIR/$tfile
9640         flocks_test 3 $DIR/$tfile
9641 }
9642 run_test 105e "Two conflicting flocks from same process"
9643
9644 test_106() { #bug 10921
9645         test_mkdir $DIR/$tdir
9646         $DIR/$tdir && error "exec $DIR/$tdir succeeded"
9647         chmod 777 $DIR/$tdir || error "chmod $DIR/$tdir failed"
9648 }
9649 run_test 106 "attempt exec of dir followed by chown of that dir"
9650
9651 test_107() {
9652         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9653
9654         CDIR=`pwd`
9655         local file=core
9656
9657         cd $DIR
9658         rm -f $file
9659
9660         local save_pattern=$(sysctl -n kernel.core_pattern)
9661         local save_uses_pid=$(sysctl -n kernel.core_uses_pid)
9662         sysctl -w kernel.core_pattern=$file
9663         sysctl -w kernel.core_uses_pid=0
9664
9665         ulimit -c unlimited
9666         sleep 60 &
9667         SLEEPPID=$!
9668
9669         sleep 1
9670
9671         kill -s 11 $SLEEPPID
9672         wait $SLEEPPID
9673         if [ -e $file ]; then
9674                 size=`stat -c%s $file`
9675                 [ $size -eq 0 ] && error "Fail to create core file $file"
9676         else
9677                 error "Fail to create core file $file"
9678         fi
9679         rm -f $file
9680         sysctl -w kernel.core_pattern=$save_pattern
9681         sysctl -w kernel.core_uses_pid=$save_uses_pid
9682         cd $CDIR
9683 }
9684 run_test 107 "Coredump on SIG"
9685
9686 test_110() {
9687         test_mkdir $DIR/$tdir
9688         test_mkdir $DIR/$tdir/$(str_repeat 'a' 255)
9689         $LFS mkdir -c $MDSCOUNT $DIR/$tdir/$(str_repeat 'b' 256) &&
9690                 error "mkdir with 256 char should fail, but did not"
9691         touch $DIR/$tdir/$(str_repeat 'x' 255) ||
9692                 error "create with 255 char failed"
9693         touch $DIR/$tdir/$(str_repeat 'y' 256) &&
9694                 error "create with 256 char should fail, but did not"
9695
9696         ls -l $DIR/$tdir
9697         rm -rf $DIR/$tdir
9698 }
9699 run_test 110 "filename length checking"
9700
9701 #
9702 # Purpose: To verify dynamic thread (OSS) creation.
9703 #
9704 test_115() {
9705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9706         remote_ost_nodsh && skip "remote OST with nodsh"
9707
9708         # Lustre does not stop service threads once they are started.
9709         # Reset number of running threads to default.
9710         stopall
9711         setupall
9712
9713         local OSTIO_pre
9714         local save_params="$TMP/sanity-$TESTNAME.parameters"
9715
9716         # Get ll_ost_io count before I/O
9717         OSTIO_pre=$(do_facet ost1 \
9718                 "$LCTL get_param ost.OSS.ost_io.threads_started | cut -d= -f2")
9719         # Exit if lustre is not running (ll_ost_io not running).
9720         [ -z "$OSTIO_pre" ] && error "no OSS threads"
9721
9722         echo "Starting with $OSTIO_pre threads"
9723         local thread_max=$((OSTIO_pre * 2))
9724         local rpc_in_flight=$((thread_max * 2))
9725         # Number of I/O Process proposed to be started.
9726         local nfiles
9727         local facets=$(get_facets OST)
9728
9729         save_lustre_params client "osc.*OST*.max_rpcs_in_flight" > $save_params
9730         save_lustre_params $facets "ost.OSS.ost_io.threads_max" >> $save_params
9731
9732         # Set in_flight to $rpc_in_flight
9733         $LCTL set_param osc.*OST*.max_rpcs_in_flight=$rpc_in_flight ||
9734                 error "Failed to set max_rpcs_in_flight to $rpc_in_flight"
9735         nfiles=${rpc_in_flight}
9736         # Set ost thread_max to $thread_max
9737         do_facet ost1 "$LCTL set_param ost.OSS.ost_io.threads_max=$thread_max"
9738
9739         # 5 Minutes should be sufficient for max number of OSS
9740         # threads(thread_max) to be created.
9741         local timeout=300
9742
9743         # Start I/O.
9744         local WTL=${WTL:-"$LUSTRE/tests/write_time_limit"}
9745         test_mkdir $DIR/$tdir
9746         for i in $(seq $nfiles); do
9747                 local file=$DIR/$tdir/${tfile}-$i
9748                 $LFS setstripe -c -1 -i 0 $file
9749                 ($WTL $file $timeout)&
9750         done
9751
9752         # I/O Started - Wait for thread_started to reach thread_max or report
9753         # error if thread_started is more than thread_max.
9754         echo "Waiting for thread_started to reach thread_max"
9755         local thread_started=0
9756         local end_time=$((SECONDS + timeout))
9757
9758         while [ $SECONDS -le $end_time ] ; do
9759                 echo -n "."
9760                 # Get ost i/o thread_started count.
9761                 thread_started=$(do_facet ost1 \
9762                         "$LCTL get_param \
9763                         ost.OSS.ost_io.threads_started | cut -d= -f2")
9764                 # Break out if thread_started is equal/greater than thread_max
9765                 if [[ $thread_started -ge $thread_max ]]; then
9766                         echo ll_ost_io thread_started $thread_started, \
9767                                 equal/greater than thread_max $thread_max
9768                         break
9769                 fi
9770                 sleep 1
9771         done
9772
9773         # Cleanup - We have the numbers, Kill i/o jobs if running.
9774         jobcount=($(jobs -p))
9775         for i in $(seq 0 $((${#jobcount[@]}-1)))
9776         do
9777                 kill -9 ${jobcount[$i]}
9778                 if [ $? -ne 0 ] ; then
9779                         echo Warning: \
9780                         Failed to Kill \'WTL\(I/O\)\' with pid ${jobcount[$i]}
9781                 fi
9782         done
9783
9784         # Cleanup files left by WTL binary.
9785         for i in $(seq $nfiles); do
9786                 local file=$DIR/$tdir/${tfile}-$i
9787                 rm -rf $file
9788                 if [ $? -ne 0 ] ; then
9789                         echo "Warning: Failed to delete file $file"
9790                 fi
9791         done
9792
9793         restore_lustre_params <$save_params
9794         rm -f $save_params || echo "Warning: delete file '$save_params' failed"
9795
9796         # Error out if no new thread has started or Thread started is greater
9797         # than thread max.
9798         if [[ $thread_started -le $OSTIO_pre ||
9799                         $thread_started -gt $thread_max ]]; then
9800                 error "ll_ost_io: thread_started $thread_started" \
9801                       "OSTIO_pre $OSTIO_pre, thread_max $thread_max." \
9802                       "No new thread started or thread started greater " \
9803                       "than thread_max."
9804         fi
9805 }
9806 run_test 115 "verify dynamic thread creation===================="
9807
9808 free_min_max () {
9809         wait_delete_completed
9810         AVAIL=($(lctl get_param -n osc.*[oO][sS][cC]-[^M]*.kbytesavail))
9811         echo "OST kbytes available: ${AVAIL[@]}"
9812         MAXV=${AVAIL[0]}
9813         MAXI=0
9814         MINV=${AVAIL[0]}
9815         MINI=0
9816         for ((i = 0; i < ${#AVAIL[@]}; i++)); do
9817                 #echo OST $i: ${AVAIL[i]}kb
9818                 if [[ ${AVAIL[i]} -gt $MAXV ]]; then
9819                         MAXV=${AVAIL[i]}
9820                         MAXI=$i
9821                 fi
9822                 if [[ ${AVAIL[i]} -lt $MINV ]]; then
9823                         MINV=${AVAIL[i]}
9824                         MINI=$i
9825                 fi
9826         done
9827         echo "Min free space: OST $MINI: $MINV"
9828         echo "Max free space: OST $MAXI: $MAXV"
9829 }
9830
9831 test_116a() { # was previously test_116()
9832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9833         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
9834         remote_mds_nodsh && skip "remote MDS with nodsh"
9835
9836         echo -n "Free space priority "
9837         do_facet $SINGLEMDS lctl get_param -n lo[vd].*-mdtlov.qos_prio_free |
9838                 head -n1
9839         declare -a AVAIL
9840         free_min_max
9841
9842         [ $MINV -eq 0 ] && skip "no free space in OST$MINI, skip"
9843         [ $MINV -gt 10000000 ] && skip "too much free space in OST$MINI, skip"
9844         trap simple_cleanup_common EXIT
9845
9846         # Check if we need to generate uneven OSTs
9847         test_mkdir -p $DIR/$tdir/OST${MINI}
9848         local FILL=$((MINV / 4))
9849         local DIFF=$((MAXV - MINV))
9850         local DIFF2=$((DIFF * 100 / MINV))
9851
9852         local threshold=$(do_facet $SINGLEMDS \
9853                 lctl get_param -n *.*MDT0000-mdtlov.qos_threshold_rr | head -n1)
9854         threshold=${threshold%%%}
9855         echo -n "Check for uneven OSTs: "
9856         echo -n "diff=${DIFF}KB (${DIFF2}%) must be > ${threshold}% ..."
9857
9858         if [[ $DIFF2 -gt $threshold ]]; then
9859                 echo "ok"
9860                 echo "Don't need to fill OST$MINI"
9861         else
9862                 # generate uneven OSTs. Write 2% over the QOS threshold value
9863                 echo "no"
9864                 DIFF=$((threshold - DIFF2 + 2))
9865                 DIFF2=$((MINV * DIFF / 100))
9866                 echo "Fill $DIFF% remaining space in OST$MINI with ${DIFF2}KB"
9867                 $LFS setstripe -i $MINI -c 1 $DIR/$tdir/OST${MINI} ||
9868                         error "setstripe failed"
9869                 DIFF=$((DIFF2 / 2048))
9870                 i=0
9871                 while [ $i -lt $DIFF ]; do
9872                         i=$((i + 1))
9873                         dd if=/dev/zero of=$DIR/$tdir/OST${MINI}/$tfile-$i \
9874                                 bs=2M count=1 2>/dev/null
9875                         echo -n .
9876                 done
9877                 echo .
9878                 sync
9879                 sleep_maxage
9880                 free_min_max
9881         fi
9882
9883         DIFF=$((MAXV - MINV))
9884         DIFF2=$((DIFF * 100 / MINV))
9885         echo -n "diff=$DIFF=$DIFF2% must be > $threshold% for QOS mode..."
9886         if [ $DIFF2 -gt $threshold ]; then
9887                 echo "ok"
9888         else
9889                 echo "failed - QOS mode won't be used"
9890                 simple_cleanup_common
9891                 skip "QOS imbalance criteria not met"
9892         fi
9893
9894         MINI1=$MINI
9895         MINV1=$MINV
9896         MAXI1=$MAXI
9897         MAXV1=$MAXV
9898
9899         # now fill using QOS
9900         $LFS setstripe -c 1 $DIR/$tdir
9901         FILL=$((FILL / 200))
9902         if [ $FILL -gt 600 ]; then
9903                 FILL=600
9904         fi
9905         echo "writing $FILL files to QOS-assigned OSTs"
9906         i=0
9907         while [ $i -lt $FILL ]; do
9908                 i=$((i + 1))
9909                 dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=200k \
9910                         count=1 2>/dev/null
9911                 echo -n .
9912         done
9913         echo "wrote $i 200k files"
9914         sync
9915         sleep_maxage
9916
9917         echo "Note: free space may not be updated, so measurements might be off"
9918         free_min_max
9919         DIFF2=$((MAXV - MINV))
9920         echo "free space delta: orig $DIFF final $DIFF2"
9921         [ $DIFF2 -gt $DIFF ] && echo "delta got worse!"
9922         DIFF=$((MINV1 - ${AVAIL[$MINI1]}))
9923         echo "Wrote ${DIFF}KB to smaller OST $MINI1"
9924         DIFF2=$((MAXV1 - ${AVAIL[$MAXI1]}))
9925         echo "Wrote ${DIFF2}KB to larger OST $MAXI1"
9926         if [[ $DIFF -gt 0 ]]; then
9927                 FILL=$((DIFF2 * 100 / DIFF - 100))
9928                 echo "Wrote ${FILL}% more data to larger OST $MAXI1"
9929         fi
9930
9931         # Figure out which files were written where
9932         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9933                awk '/'$MINI1': / {print $2; exit}')
9934         echo $UUID
9935         MINC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9936         echo "$MINC files created on smaller OST $MINI1"
9937         UUID=$(lctl get_param -n lov.${FSNAME}-clilov-*.target_obd |
9938                awk '/'$MAXI1': / {print $2; exit}')
9939         echo $UUID
9940         MAXC=$($LFS getstripe --ost $UUID $DIR/$tdir | grep $DIR | wc -l)
9941         echo "$MAXC files created on larger OST $MAXI1"
9942         if [[ $MINC -gt 0 ]]; then
9943                 FILL=$((MAXC * 100 / MINC - 100))
9944                 echo "Wrote ${FILL}% more files to larger OST $MAXI1"
9945         fi
9946         [[ $MAXC -gt $MINC ]] ||
9947                 error_ignore LU-9 "stripe QOS didn't balance free space"
9948         simple_cleanup_common
9949 }
9950 run_test 116a "stripe QOS: free space balance ==================="
9951
9952 test_116b() { # LU-2093
9953         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9954         remote_mds_nodsh && skip "remote MDS with nodsh"
9955
9956 #define OBD_FAIL_MDS_OSC_CREATE_FAIL     0x147
9957         local old_rr=$(do_facet $SINGLEMDS lctl get_param -n \
9958                        lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr | head -1)
9959         [ -z "$old_rr" ] && skip "no QOS"
9960         do_facet $SINGLEMDS lctl set_param \
9961                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=0
9962         mkdir -p $DIR/$tdir
9963         do_facet $SINGLEMDS lctl set_param fail_loc=0x147
9964         createmany -o $DIR/$tdir/f- 20 || error "can't create"
9965         do_facet $SINGLEMDS lctl set_param fail_loc=0
9966         rm -rf $DIR/$tdir
9967         do_facet $SINGLEMDS lctl set_param \
9968                 lo[vd].$FSNAME-MDT0000-mdtlov.qos_threshold_rr=$old_rr
9969 }
9970 run_test 116b "QoS shouldn't LBUG if not enough OSTs found on the 2nd pass"
9971
9972 test_117() # bug 10891
9973 {
9974         [ $PARALLEL == "yes" ] && skip "skip parallel run"
9975
9976         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
9977         #define OBD_FAIL_OST_SETATTR_CREDITS 0x21e
9978         lctl set_param fail_loc=0x21e
9979         > $DIR/$tfile || error "truncate failed"
9980         lctl set_param fail_loc=0
9981         echo "Truncate succeeded."
9982         rm -f $DIR/$tfile
9983 }
9984 run_test 117 "verify osd extend =========="
9985
9986 NO_SLOW_RESENDCOUNT=4
9987 export OLD_RESENDCOUNT=""
9988 set_resend_count () {
9989         local PROC_RESENDCOUNT="osc.${FSNAME}-OST*-osc-*.resend_count"
9990         OLD_RESENDCOUNT=$(lctl get_param -n $PROC_RESENDCOUNT | head -n1)
9991         lctl set_param -n $PROC_RESENDCOUNT $1
9992         echo resend_count is set to $(lctl get_param -n $PROC_RESENDCOUNT)
9993 }
9994
9995 # for reduce test_118* time (b=14842)
9996 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
9997
9998 # Reset async IO behavior after error case
9999 reset_async() {
10000         FILE=$DIR/reset_async
10001
10002         # Ensure all OSCs are cleared
10003         $LFS setstripe -c -1 $FILE
10004         dd if=/dev/zero of=$FILE bs=64k count=$OSTCOUNT
10005         sync
10006         rm $FILE
10007 }
10008
10009 test_118a() #bug 11710
10010 {
10011         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10012
10013         reset_async
10014
10015         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10016         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10017         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10018
10019         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10020                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10021                 return 1;
10022         fi
10023         rm -f $DIR/$tfile
10024 }
10025 run_test 118a "verify O_SYNC works =========="
10026
10027 test_118b()
10028 {
10029         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10030         remote_ost_nodsh && skip "remote OST with nodsh"
10031
10032         reset_async
10033
10034         #define OBD_FAIL_SRV_ENOENT 0x217
10035         set_nodes_failloc "$(osts_nodes)" 0x217
10036         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10037         RC=$?
10038         set_nodes_failloc "$(osts_nodes)" 0
10039         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10040         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10041                     grep -c writeback)
10042
10043         if [[ $RC -eq 0 ]]; then
10044                 error "Must return error due to dropped pages, rc=$RC"
10045                 return 1;
10046         fi
10047
10048         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10049                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10050                 return 1;
10051         fi
10052
10053         echo "Dirty pages not leaked on ENOENT"
10054
10055         # Due to the above error the OSC will issue all RPCs syncronously
10056         # until a subsequent RPC completes successfully without error.
10057         $MULTIOP $DIR/$tfile Ow4096yc
10058         rm -f $DIR/$tfile
10059
10060         return 0
10061 }
10062 run_test 118b "Reclaim dirty pages on fatal error =========="
10063
10064 test_118c()
10065 {
10066         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10067
10068         # for 118c, restore the original resend count, LU-1940
10069         [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] &&
10070                                 set_resend_count $OLD_RESENDCOUNT
10071         remote_ost_nodsh && skip "remote OST with nodsh"
10072
10073         reset_async
10074
10075         #define OBD_FAIL_OST_EROFS               0x216
10076         set_nodes_failloc "$(osts_nodes)" 0x216
10077
10078         # multiop should block due to fsync until pages are written
10079         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10080         MULTIPID=$!
10081         sleep 1
10082
10083         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10084                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10085         fi
10086
10087         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10088                     grep -c writeback)
10089         if [[ $WRITEBACK -eq 0 ]]; then
10090                 error "No page in writeback, writeback=$WRITEBACK"
10091         fi
10092
10093         set_nodes_failloc "$(osts_nodes)" 0
10094         wait $MULTIPID
10095         RC=$?
10096         if [[ $RC -ne 0 ]]; then
10097                 error "Multiop fsync failed, rc=$RC"
10098         fi
10099
10100         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10101         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10102                     grep -c writeback)
10103         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10104                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10105         fi
10106
10107         rm -f $DIR/$tfile
10108         echo "Dirty pages flushed via fsync on EROFS"
10109         return 0
10110 }
10111 run_test 118c "Fsync blocks on EROFS until dirty pages are flushed =========="
10112
10113 # continue to use small resend count to reduce test_118* time (b=14842)
10114 [ "$SLOW" = "no" ] && set_resend_count $NO_SLOW_RESENDCOUNT
10115
10116 test_118d()
10117 {
10118         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10119         remote_ost_nodsh && skip "remote OST with nodsh"
10120
10121         reset_async
10122
10123         #define OBD_FAIL_OST_BRW_PAUSE_BULK
10124         set_nodes_failloc "$(osts_nodes)" 0x214
10125         # multiop should block due to fsync until pages are written
10126         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10127         MULTIPID=$!
10128         sleep 1
10129
10130         if [[ `ps h -o comm -p $MULTIPID` != "multiop" ]]; then
10131                 error "Multiop failed to block on fsync, pid=$MULTIPID"
10132         fi
10133
10134         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10135                     grep -c writeback)
10136         if [[ $WRITEBACK -eq 0 ]]; then
10137                 error "No page in writeback, writeback=$WRITEBACK"
10138         fi
10139
10140         wait $MULTIPID || error "Multiop fsync failed, rc=$?"
10141         set_nodes_failloc "$(osts_nodes)" 0
10142
10143         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10144         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10145                     grep -c writeback)
10146         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10147                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10148         fi
10149
10150         rm -f $DIR/$tfile
10151         echo "Dirty pages gaurenteed flushed via fsync"
10152         return 0
10153 }
10154 run_test 118d "Fsync validation inject a delay of the bulk =========="
10155
10156 test_118f() {
10157         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10158
10159         reset_async
10160
10161         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
10162         lctl set_param fail_loc=0x8000040a
10163
10164         # Should simulate EINVAL error which is fatal
10165         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10166         RC=$?
10167         if [[ $RC -eq 0 ]]; then
10168                 error "Must return error due to dropped pages, rc=$RC"
10169         fi
10170
10171         lctl set_param fail_loc=0x0
10172
10173         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10174         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10175         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10176                     grep -c writeback)
10177         if [[ $LOCKED -ne 0 ]]; then
10178                 error "Locked pages remain in cache, locked=$LOCKED"
10179         fi
10180
10181         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10182                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10183         fi
10184
10185         rm -f $DIR/$tfile
10186         echo "No pages locked after fsync"
10187
10188         reset_async
10189         return 0
10190 }
10191 run_test 118f "Simulate unrecoverable OSC side error =========="
10192
10193 test_118g() {
10194         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10195
10196         reset_async
10197
10198         #define OBD_FAIL_OSC_BRW_PREP_REQ        0x406
10199         lctl set_param fail_loc=0x406
10200
10201         # simulate local -ENOMEM
10202         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10203         RC=$?
10204
10205         lctl set_param fail_loc=0
10206         if [[ $RC -eq 0 ]]; then
10207                 error "Must return error due to dropped pages, rc=$RC"
10208         fi
10209
10210         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10211         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10212         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10213                         grep -c writeback)
10214         if [[ $LOCKED -ne 0 ]]; then
10215                 error "Locked pages remain in cache, locked=$LOCKED"
10216         fi
10217
10218         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10219                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10220         fi
10221
10222         rm -f $DIR/$tfile
10223         echo "No pages locked after fsync"
10224
10225         reset_async
10226         return 0
10227 }
10228 run_test 118g "Don't stay in wait if we got local -ENOMEM  =========="
10229
10230 test_118h() {
10231         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10232         remote_ost_nodsh && skip "remote OST with nodsh"
10233
10234         reset_async
10235
10236         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10237         set_nodes_failloc "$(osts_nodes)" 0x20e
10238         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10239         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10240         RC=$?
10241
10242         set_nodes_failloc "$(osts_nodes)" 0
10243         if [[ $RC -eq 0 ]]; then
10244                 error "Must return error due to dropped pages, rc=$RC"
10245         fi
10246
10247         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10248         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10249         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache |
10250                     grep -c writeback)
10251         if [[ $LOCKED -ne 0 ]]; then
10252                 error "Locked pages remain in cache, locked=$LOCKED"
10253         fi
10254
10255         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10256                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10257         fi
10258
10259         rm -f $DIR/$tfile
10260         echo "No pages locked after fsync"
10261
10262         return 0
10263 }
10264 run_test 118h "Verify timeout in handling recoverables errors  =========="
10265
10266 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10267
10268 test_118i() {
10269         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10270         remote_ost_nodsh && skip "remote OST with nodsh"
10271
10272         reset_async
10273
10274         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10275         set_nodes_failloc "$(osts_nodes)" 0x20e
10276
10277         # Should simulate ENOMEM error which is recoverable and should be handled by timeout
10278         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c &
10279         PID=$!
10280         sleep 5
10281         set_nodes_failloc "$(osts_nodes)" 0
10282
10283         wait $PID
10284         RC=$?
10285         if [[ $RC -ne 0 ]]; then
10286                 error "got error, but should be not, rc=$RC"
10287         fi
10288
10289         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10290         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10291         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10292         if [[ $LOCKED -ne 0 ]]; then
10293                 error "Locked pages remain in cache, locked=$LOCKED"
10294         fi
10295
10296         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10297                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10298         fi
10299
10300         rm -f $DIR/$tfile
10301         echo "No pages locked after fsync"
10302
10303         return 0
10304 }
10305 run_test 118i "Fix error before timeout in recoverable error  =========="
10306
10307 [ "$SLOW" = "no" ] && set_resend_count 4
10308
10309 test_118j() {
10310         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10311         remote_ost_nodsh && skip "remote OST with nodsh"
10312
10313         reset_async
10314
10315         #define OBD_FAIL_OST_BRW_WRITE_BULK2     0x220
10316         set_nodes_failloc "$(osts_nodes)" 0x220
10317
10318         # return -EIO from OST
10319         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:O_SYNC:w4096c
10320         RC=$?
10321         set_nodes_failloc "$(osts_nodes)" 0x0
10322         if [[ $RC -eq 0 ]]; then
10323                 error "Must return error due to dropped pages, rc=$RC"
10324         fi
10325
10326         LOCKED=$(lctl get_param -n llite.*.dump_page_cache | grep -c locked)
10327         DIRTY=$(lctl get_param -n llite.*.dump_page_cache | grep -c dirty)
10328         WRITEBACK=$(lctl get_param -n llite.*.dump_page_cache | grep -c writeback)
10329         if [[ $LOCKED -ne 0 ]]; then
10330                 error "Locked pages remain in cache, locked=$LOCKED"
10331         fi
10332
10333         # in recoverable error on OST we want resend and stay until it finished
10334         if [[ $DIRTY -ne 0 || $WRITEBACK -ne 0 ]]; then
10335                 error "Dirty pages not flushed to disk, dirty=$DIRTY, writeback=$WRITEBACK"
10336         fi
10337
10338         rm -f $DIR/$tfile
10339         echo "No pages locked after fsync"
10340
10341         return 0
10342 }
10343 run_test 118j "Simulate unrecoverable OST side error =========="
10344
10345 test_118k()
10346 {
10347         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10348         remote_ost_nodsh && skip "remote OSTs with nodsh"
10349
10350         #define OBD_FAIL_OST_BRW_WRITE_BULK      0x20e
10351         set_nodes_failloc "$(osts_nodes)" 0x20e
10352         test_mkdir $DIR/$tdir
10353
10354         for ((i=0;i<10;i++)); do
10355                 (dd if=/dev/zero of=$DIR/$tdir/$tfile-$i bs=1M count=10 || \
10356                         error "dd to $DIR/$tdir/$tfile-$i failed" )&
10357                 SLEEPPID=$!
10358                 sleep 0.500s
10359                 kill $SLEEPPID
10360                 wait $SLEEPPID
10361         done
10362
10363         set_nodes_failloc "$(osts_nodes)" 0
10364         rm -rf $DIR/$tdir
10365 }
10366 run_test 118k "bio alloc -ENOMEM and IO TERM handling ========="
10367
10368 test_118l() # LU-646
10369 {
10370         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10371
10372         test_mkdir $DIR/$tdir
10373         $MULTIOP $DIR/$tdir Dy || error "fsync dir failed"
10374         rm -rf $DIR/$tdir
10375 }
10376 run_test 118l "fsync dir"
10377
10378 test_118m() # LU-3066
10379 {
10380         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10381
10382         test_mkdir $DIR/$tdir
10383         $MULTIOP $DIR/$tdir DY || error "fdatasync dir failed"
10384         rm -rf $DIR/$tdir
10385 }
10386 run_test 118m "fdatasync dir ========="
10387
10388 [ "$SLOW" = "no" ] && [ -n "$OLD_RESENDCOUNT" ] && set_resend_count $OLD_RESENDCOUNT
10389
10390 test_118n()
10391 {
10392         local begin
10393         local end
10394
10395         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10396         remote_ost_nodsh && skip "remote OSTs with nodsh"
10397
10398         # Sleep to avoid a cached response.
10399         #define OBD_STATFS_CACHE_SECONDS 1
10400         sleep 2
10401
10402         # Inject a 10 second delay in the OST_STATFS handler.
10403         #define OBD_FAIL_OST_STATFS_DELAY 0x242
10404         set_nodes_failloc "$(osts_nodes)" 0x242
10405
10406         begin=$SECONDS
10407         stat --file-system $MOUNT > /dev/null
10408         end=$SECONDS
10409
10410         set_nodes_failloc "$(osts_nodes)" 0
10411
10412         if ((end - begin > 20)); then
10413             error "statfs took $((end - begin)) seconds, expected 10"
10414         fi
10415 }
10416 run_test 118n "statfs() sends OST_STATFS requests in parallel"
10417
10418 test_119a() # bug 11737
10419 {
10420         BSIZE=$((512 * 1024))
10421         directio write $DIR/$tfile 0 1 $BSIZE
10422         # We ask to read two blocks, which is more than a file size.
10423         # directio will indicate an error when requested and actual
10424         # sizes aren't equeal (a normal situation in this case) and
10425         # print actual read amount.
10426         NOB=`directio read $DIR/$tfile 0 2 $BSIZE | awk '/error/ {print $6}'`
10427         if [ "$NOB" != "$BSIZE" ]; then
10428                 error "read $NOB bytes instead of $BSIZE"
10429         fi
10430         rm -f $DIR/$tfile
10431 }
10432 run_test 119a "Short directIO read must return actual read amount"
10433
10434 test_119b() # bug 11737
10435 {
10436         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
10437
10438         $LFS setstripe -c 2 $DIR/$tfile || error "setstripe failed"
10439         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 seek=1 || error "dd failed"
10440         sync
10441         $MULTIOP $DIR/$tfile oO_RDONLY:O_DIRECT:r$((2048 * 1024)) ||
10442                 error "direct read failed"
10443         rm -f $DIR/$tfile
10444 }
10445 run_test 119b "Sparse directIO read must return actual read amount"
10446
10447 test_119c() # bug 13099
10448 {
10449         BSIZE=1048576
10450         directio write $DIR/$tfile 3 1 $BSIZE || error "direct write failed"
10451         directio readhole $DIR/$tfile 0 2 $BSIZE || error "reading hole failed"
10452         rm -f $DIR/$tfile
10453 }
10454 run_test 119c "Testing for direct read hitting hole"
10455
10456 test_119d() # bug 15950
10457 {
10458         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10459
10460         MAX_RPCS_IN_FLIGHT=`$LCTL get_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight`
10461         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight 1
10462         BSIZE=1048576
10463         $LFS setstripe $DIR/$tfile -i 0 -c 1 || error "setstripe failed"
10464         $DIRECTIO write $DIR/$tfile 0 1 $BSIZE || error "first directio failed"
10465         #define OBD_FAIL_OSC_DIO_PAUSE           0x40d
10466         lctl set_param fail_loc=0x40d
10467         $DIRECTIO write $DIR/$tfile 1 4 $BSIZE &
10468         pid_dio=$!
10469         sleep 1
10470         cat $DIR/$tfile > /dev/null &
10471         lctl set_param fail_loc=0
10472         pid_reads=$!
10473         wait $pid_dio
10474         log "the DIO writes have completed, now wait for the reads (should not block very long)"
10475         sleep 2
10476         [ -n "`ps h -p $pid_reads -o comm`" ] && \
10477         error "the read rpcs have not completed in 2s"
10478         rm -f $DIR/$tfile
10479         $LCTL set_param -n osc.*OST0000-osc-[^mM]*.max_rpcs_in_flight $MAX_RPCS_IN_FLIGHT
10480 }
10481 run_test 119d "The DIO path should try to send a new rpc once one is completed"
10482
10483 test_120a() {
10484         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10485         remote_mds_nodsh && skip "remote MDS with nodsh"
10486         test_mkdir -i0 -c1 $DIR/$tdir
10487         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10488                 skip_env "no early lock cancel on server"
10489
10490         lru_resize_disable mdc
10491         lru_resize_disable osc
10492         cancel_lru_locks mdc
10493         # asynchronous object destroy at MDT could cause bl ast to client
10494         cancel_lru_locks osc
10495
10496         stat $DIR/$tdir > /dev/null
10497         can1=$(do_facet mds1 \
10498                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10499                awk '/ldlm_cancel/ {print $2}')
10500         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10501                awk '/ldlm_bl_callback/ {print $2}')
10502         test_mkdir -i0 -c1 $DIR/$tdir/d1
10503         can2=$(do_facet mds1 \
10504                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10505                awk '/ldlm_cancel/ {print $2}')
10506         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10507                awk '/ldlm_bl_callback/ {print $2}')
10508         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10509         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10510         lru_resize_enable mdc
10511         lru_resize_enable osc
10512 }
10513 run_test 120a "Early Lock Cancel: mkdir test"
10514
10515 test_120b() {
10516         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10517         remote_mds_nodsh && skip "remote MDS with nodsh"
10518         test_mkdir $DIR/$tdir
10519         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10520                 skip_env "no early lock cancel on server"
10521
10522         lru_resize_disable mdc
10523         lru_resize_disable osc
10524         cancel_lru_locks mdc
10525         stat $DIR/$tdir > /dev/null
10526         can1=$(do_facet $SINGLEMDS \
10527                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10528                awk '/ldlm_cancel/ {print $2}')
10529         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10530                awk '/ldlm_bl_callback/ {print $2}')
10531         touch $DIR/$tdir/f1
10532         can2=$(do_facet $SINGLEMDS \
10533                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10534                awk '/ldlm_cancel/ {print $2}')
10535         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10536                awk '/ldlm_bl_callback/ {print $2}')
10537         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10538         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10539         lru_resize_enable mdc
10540         lru_resize_enable osc
10541 }
10542 run_test 120b "Early Lock Cancel: create test"
10543
10544 test_120c() {
10545         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10546         remote_mds_nodsh && skip "remote MDS with nodsh"
10547         test_mkdir -i0 -c1 $DIR/$tdir
10548         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10549                 skip "no early lock cancel on server"
10550
10551         lru_resize_disable mdc
10552         lru_resize_disable osc
10553         test_mkdir -i0 -c1 $DIR/$tdir/d1
10554         test_mkdir -i0 -c1 $DIR/$tdir/d2
10555         touch $DIR/$tdir/d1/f1
10556         cancel_lru_locks mdc
10557         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 > /dev/null
10558         can1=$(do_facet mds1 \
10559                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10560                awk '/ldlm_cancel/ {print $2}')
10561         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10562                awk '/ldlm_bl_callback/ {print $2}')
10563         ln $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10564         can2=$(do_facet mds1 \
10565                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10566                awk '/ldlm_cancel/ {print $2}')
10567         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10568                awk '/ldlm_bl_callback/ {print $2}')
10569         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10570         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10571         lru_resize_enable mdc
10572         lru_resize_enable osc
10573 }
10574 run_test 120c "Early Lock Cancel: link test"
10575
10576 test_120d() {
10577         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10578         remote_mds_nodsh && skip "remote MDS with nodsh"
10579         test_mkdir -i0 -c1 $DIR/$tdir
10580         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10581                 skip_env "no early lock cancel on server"
10582
10583         lru_resize_disable mdc
10584         lru_resize_disable osc
10585         touch $DIR/$tdir
10586         cancel_lru_locks mdc
10587         stat $DIR/$tdir > /dev/null
10588         can1=$(do_facet mds1 \
10589                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10590                awk '/ldlm_cancel/ {print $2}')
10591         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10592                awk '/ldlm_bl_callback/ {print $2}')
10593         chmod a+x $DIR/$tdir
10594         can2=$(do_facet mds1 \
10595                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10596                awk '/ldlm_cancel/ {print $2}')
10597         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10598                awk '/ldlm_bl_callback/ {print $2}')
10599         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10600         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10601         lru_resize_enable mdc
10602         lru_resize_enable osc
10603 }
10604 run_test 120d "Early Lock Cancel: setattr test"
10605
10606 test_120e() {
10607         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10608         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10609                 skip_env "no early lock cancel on server"
10610         remote_mds_nodsh && skip "remote MDS with nodsh"
10611
10612         local dlmtrace_set=false
10613
10614         test_mkdir -i0 -c1 $DIR/$tdir
10615         lru_resize_disable mdc
10616         lru_resize_disable osc
10617         ! $LCTL get_param debug | grep -q dlmtrace &&
10618                 $LCTL set_param debug=+dlmtrace && dlmtrace_set=true
10619         dd if=/dev/zero of=$DIR/$tdir/f1 count=1
10620         cancel_lru_locks mdc
10621         cancel_lru_locks osc
10622         dd if=$DIR/$tdir/f1 of=/dev/null
10623         stat $DIR/$tdir $DIR/$tdir/f1 > /dev/null
10624         # XXX client can not do early lock cancel of OST lock
10625         # during unlink (LU-4206), so cancel osc lock now.
10626         sleep 2
10627         cancel_lru_locks osc
10628         can1=$(do_facet mds1 \
10629                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10630                awk '/ldlm_cancel/ {print $2}')
10631         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10632                awk '/ldlm_bl_callback/ {print $2}')
10633         unlink $DIR/$tdir/f1
10634         sleep 5
10635         can2=$(do_facet mds1 \
10636                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10637                awk '/ldlm_cancel/ {print $2}')
10638         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10639                awk '/ldlm_bl_callback/ {print $2}')
10640         [ $can1 -ne $can2 ] && error "$((can2 - can1)) cancel RPC occured" &&
10641                 $LCTL dk $TMP/cancel.debug.txt
10642         [ $blk1 -ne $blk2 ] && error "$((blk2 - blk1)) blocking RPC occured" &&
10643                 $LCTL dk $TMP/blocking.debug.txt
10644         $dlmtrace_set && $LCTL set_param debug=-dlmtrace
10645         lru_resize_enable mdc
10646         lru_resize_enable osc
10647 }
10648 run_test 120e "Early Lock Cancel: unlink test"
10649
10650 test_120f() {
10651         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10652         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10653                 skip_env "no early lock cancel on server"
10654         remote_mds_nodsh && skip "remote MDS with nodsh"
10655
10656         test_mkdir -i0 -c1 $DIR/$tdir
10657         lru_resize_disable mdc
10658         lru_resize_disable osc
10659         test_mkdir -i0 -c1 $DIR/$tdir/d1
10660         test_mkdir -i0 -c1 $DIR/$tdir/d2
10661         dd if=/dev/zero of=$DIR/$tdir/d1/f1 count=1
10662         dd if=/dev/zero of=$DIR/$tdir/d2/f2 count=1
10663         cancel_lru_locks mdc
10664         cancel_lru_locks osc
10665         dd if=$DIR/$tdir/d1/f1 of=/dev/null
10666         dd if=$DIR/$tdir/d2/f2 of=/dev/null
10667         stat $DIR/$tdir/d1 $DIR/$tdir/d2 $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2 > /dev/null
10668         # XXX client can not do early lock cancel of OST lock
10669         # during rename (LU-4206), so cancel osc lock now.
10670         sleep 2
10671         cancel_lru_locks osc
10672         can1=$(do_facet mds1 \
10673                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10674                awk '/ldlm_cancel/ {print $2}')
10675         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10676                awk '/ldlm_bl_callback/ {print $2}')
10677         mrename $DIR/$tdir/d1/f1 $DIR/$tdir/d2/f2
10678         sleep 5
10679         can2=$(do_facet mds1 \
10680                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10681                awk '/ldlm_cancel/ {print $2}')
10682         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10683                awk '/ldlm_bl_callback/ {print $2}')
10684         [ $can1 -eq $can2 ] || error $((can2-can1)) "cancel RPC occured."
10685         [ $blk1 -eq $blk2 ] || error $((blk2-blk1)) "blocking RPC occured."
10686         lru_resize_enable mdc
10687         lru_resize_enable osc
10688 }
10689 run_test 120f "Early Lock Cancel: rename test"
10690
10691 test_120g() {
10692         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10693         $LCTL get_param -n mdc.*.connect_flags | grep -q early_lock_cancel ||
10694                 skip_env "no early lock cancel on server"
10695         remote_mds_nodsh && skip "remote MDS with nodsh"
10696
10697         lru_resize_disable mdc
10698         lru_resize_disable osc
10699         count=10000
10700         echo create $count files
10701         test_mkdir $DIR/$tdir
10702         cancel_lru_locks mdc
10703         cancel_lru_locks osc
10704         t0=$(date +%s)
10705
10706         can0=$(do_facet $SINGLEMDS \
10707                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10708                awk '/ldlm_cancel/ {print $2}')
10709         blk0=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10710                awk '/ldlm_bl_callback/ {print $2}')
10711         createmany -o $DIR/$tdir/f $count
10712         sync
10713         can1=$(do_facet $SINGLEMDS \
10714                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10715                awk '/ldlm_cancel/ {print $2}')
10716         blk1=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10717                awk '/ldlm_bl_callback/ {print $2}')
10718         t1=$(date +%s)
10719         echo total: $((can1-can0)) cancels, $((blk1-blk0)) blockings
10720         echo rm $count files
10721         rm -r $DIR/$tdir
10722         sync
10723         can2=$(do_facet $SINGLEMDS \
10724                "$LCTL get_param -n ldlm.services.ldlm_canceld.stats" |
10725                awk '/ldlm_cancel/ {print $2}')
10726         blk2=$($LCTL get_param -n ldlm.services.ldlm_cbd.stats |
10727                awk '/ldlm_bl_callback/ {print $2}')
10728         t2=$(date +%s)
10729         echo total: $count removes in $((t2-t1))
10730         echo total: $((can2-can1)) cancels, $((blk2-blk1)) blockings
10731         sleep 2
10732         # wait for commitment of removal
10733         lru_resize_enable mdc
10734         lru_resize_enable osc
10735 }
10736 run_test 120g "Early Lock Cancel: performance test"
10737
10738 test_121() { #bug #10589
10739         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10740
10741         rm -rf $DIR/$tfile
10742         writes=$(LANG=C dd if=/dev/zero of=$DIR/$tfile count=1 2>&1 | awk -F '+' '/out$/ {print $1}')
10743 #define OBD_FAIL_LDLM_CANCEL_RACE        0x310
10744         lctl set_param fail_loc=0x310
10745         cancel_lru_locks osc > /dev/null
10746         reads=$(LANG=C dd if=$DIR/$tfile of=/dev/null 2>&1 | awk -F '+' '/in$/ {print $1}')
10747         lctl set_param fail_loc=0
10748         [[ $reads -eq $writes ]] ||
10749                 error "read $reads blocks, must be $writes blocks"
10750 }
10751 run_test 121 "read cancel race ========="
10752
10753 test_123a() { # was test 123, statahead(bug 11401)
10754         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10755
10756         SLOWOK=0
10757         if ! grep -q "processor.*: 1" /proc/cpuinfo; then
10758                 log "testing UP system. Performance may be lower than expected."
10759                 SLOWOK=1
10760         fi
10761
10762         rm -rf $DIR/$tdir
10763         test_mkdir $DIR/$tdir
10764         NUMFREE=$(df -i -P $DIR | tail -n 1 | awk '{ print $4 }')
10765         [[ $NUMFREE -gt 100000 ]] && NUMFREE=100000 || NUMFREE=$((NUMFREE-1000))
10766         MULT=10
10767         for ((i=100, j=0; i<=$NUMFREE; j=$i, i=$((i * MULT)) )); do
10768                 createmany -o $DIR/$tdir/$tfile $j $((i - j))
10769
10770                 max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10771                 lctl set_param -n llite.*.statahead_max 0
10772                 lctl get_param llite.*.statahead_max
10773                 cancel_lru_locks mdc
10774                 cancel_lru_locks osc
10775                 stime=`date +%s`
10776                 time ls -l $DIR/$tdir | wc -l
10777                 etime=`date +%s`
10778                 delta=$((etime - stime))
10779                 log "ls $i files without statahead: $delta sec"
10780                 lctl set_param llite.*.statahead_max=$max
10781
10782                 swrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10783                 lctl get_param -n llite.*.statahead_max | grep '[0-9]'
10784                 cancel_lru_locks mdc
10785                 cancel_lru_locks osc
10786                 stime=`date +%s`
10787                 time ls -l $DIR/$tdir | wc -l
10788                 etime=`date +%s`
10789                 delta_sa=$((etime - stime))
10790                 log "ls $i files with statahead: $delta_sa sec"
10791                 lctl get_param -n llite.*.statahead_stats
10792                 ewrong=`lctl get_param -n llite.*.statahead_stats | grep "statahead wrong:" | awk '{print $3}'`
10793
10794                 [[ $swrong -lt $ewrong ]] &&
10795                         log "statahead was stopped, maybe too many locks held!"
10796                 [[ $delta -eq 0 || $delta_sa -eq 0 ]] && continue
10797
10798                 if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10799                     max=`lctl get_param -n llite.*.statahead_max | head -n 1`
10800                     lctl set_param -n llite.*.statahead_max 0
10801                     lctl get_param llite.*.statahead_max
10802                     cancel_lru_locks mdc
10803                     cancel_lru_locks osc
10804                     stime=`date +%s`
10805                     time ls -l $DIR/$tdir | wc -l
10806                     etime=`date +%s`
10807                     delta=$((etime - stime))
10808                     log "ls $i files again without statahead: $delta sec"
10809                     lctl set_param llite.*.statahead_max=$max
10810                     if [ $((delta_sa * 100)) -gt $((delta * 105)) -a $delta_sa -gt $((delta + 2)) ]; then
10811                         if [  $SLOWOK -eq 0 ]; then
10812                                 error "ls $i files is slower with statahead!"
10813                         else
10814                                 log "ls $i files is slower with statahead!"
10815                         fi
10816                         break
10817                     fi
10818                 fi
10819
10820                 [ $delta -gt 20 ] && break
10821                 [ $delta -gt 8 ] && MULT=$((50 / delta))
10822                 [ "$SLOW" = "no" -a $delta -gt 5 ] && break
10823         done
10824         log "ls done"
10825
10826         stime=`date +%s`
10827         rm -r $DIR/$tdir
10828         sync
10829         etime=`date +%s`
10830         delta=$((etime - stime))
10831         log "rm -r $DIR/$tdir/: $delta seconds"
10832         log "rm done"
10833         lctl get_param -n llite.*.statahead_stats
10834 }
10835 run_test 123a "verify statahead work"
10836
10837 test_123b () { # statahead(bug 15027)
10838         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10839
10840         test_mkdir $DIR/$tdir
10841         createmany -o $DIR/$tdir/$tfile-%d 1000
10842
10843         cancel_lru_locks mdc
10844         cancel_lru_locks osc
10845
10846 #define OBD_FAIL_MDC_GETATTR_ENQUEUE     0x803
10847         lctl set_param fail_loc=0x80000803
10848         ls -lR $DIR/$tdir > /dev/null
10849         log "ls done"
10850         lctl set_param fail_loc=0x0
10851         lctl get_param -n llite.*.statahead_stats
10852         rm -r $DIR/$tdir
10853         sync
10854
10855 }
10856 run_test 123b "not panic with network error in statahead enqueue (bug 15027)"
10857
10858 test_124a() {
10859         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10860         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10861                 skip_env "no lru resize on server"
10862
10863         local NR=2000
10864
10865         test_mkdir $DIR/$tdir
10866
10867         log "create $NR files at $DIR/$tdir"
10868         createmany -o $DIR/$tdir/f $NR ||
10869                 error "failed to create $NR files in $DIR/$tdir"
10870
10871         cancel_lru_locks mdc
10872         ls -l $DIR/$tdir > /dev/null
10873
10874         local NSDIR=""
10875         local LRU_SIZE=0
10876         for VALUE in $($LCTL get_param ldlm.namespaces.*mdc-*.lru_size); do
10877                 local PARAM=$(echo ${VALUE[0]} | cut -d "=" -f1)
10878                 LRU_SIZE=$($LCTL get_param -n $PARAM)
10879                 if [[ $LRU_SIZE -gt $(default_lru_size) ]]; then
10880                         NSDIR=$(echo $PARAM | cut -d "." -f1-3)
10881                         log "NSDIR=$NSDIR"
10882                         log "NS=$(basename $NSDIR)"
10883                         break
10884                 fi
10885         done
10886
10887         if [[ -z "$NSDIR" || $LRU_SIZE -lt $(default_lru_size) ]]; then
10888                 skip "Not enough cached locks created!"
10889         fi
10890         log "LRU=$LRU_SIZE"
10891
10892         local SLEEP=30
10893
10894         # We know that lru resize allows one client to hold $LIMIT locks
10895         # for 10h. After that locks begin to be killed by client.
10896         local MAX_HRS=10
10897         local LIMIT=$($LCTL get_param -n $NSDIR.pool.limit)
10898         log "LIMIT=$LIMIT"
10899         if [ $LIMIT -lt $LRU_SIZE ]; then
10900                 skip "Limit is too small $LIMIT"
10901         fi
10902
10903         # Make LVF so higher that sleeping for $SLEEP is enough to _start_
10904         # killing locks. Some time was spent for creating locks. This means
10905         # that up to the moment of sleep finish we must have killed some of
10906         # them (10-100 locks). This depends on how fast ther were created.
10907         # Many of them were touched in almost the same moment and thus will
10908         # be killed in groups.
10909         local LVF=$(($MAX_HRS * 60 * 60 / $SLEEP * $LIMIT / $LRU_SIZE))
10910
10911         # Use $LRU_SIZE_B here to take into account real number of locks
10912         # created in the case of CMD, LRU_SIZE_B != $NR in most of cases
10913         local LRU_SIZE_B=$LRU_SIZE
10914         log "LVF=$LVF"
10915         local OLD_LVF=$($LCTL get_param -n $NSDIR.pool.lock_volume_factor)
10916         log "OLD_LVF=$OLD_LVF"
10917         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $LVF
10918
10919         # Let's make sure that we really have some margin. Client checks
10920         # cached locks every 10 sec.
10921         SLEEP=$((SLEEP+20))
10922         log "Sleep ${SLEEP} sec"
10923         local SEC=0
10924         while ((SEC<$SLEEP)); do
10925                 echo -n "..."
10926                 sleep 5
10927                 SEC=$((SEC+5))
10928                 LRU_SIZE=$($LCTL get_param -n $NSDIR/lru_size)
10929                 echo -n "$LRU_SIZE"
10930         done
10931         echo ""
10932         $LCTL set_param -n $NSDIR.pool.lock_volume_factor $OLD_LVF
10933         local LRU_SIZE_A=$($LCTL get_param -n $NSDIR.lru_size)
10934
10935         [[ $LRU_SIZE_B -gt $LRU_SIZE_A ]] || {
10936                 error "No locks dropped in ${SLEEP}s. LRU size: $LRU_SIZE_A"
10937                 unlinkmany $DIR/$tdir/f $NR
10938                 return
10939         }
10940
10941         log "Dropped "$((LRU_SIZE_B-LRU_SIZE_A))" locks in ${SLEEP}s"
10942         log "unlink $NR files at $DIR/$tdir"
10943         unlinkmany $DIR/$tdir/f $NR
10944 }
10945 run_test 124a "lru resize ======================================="
10946
10947 get_max_pool_limit()
10948 {
10949         local limit=$($LCTL get_param \
10950                       -n ldlm.namespaces.*-MDT0000-mdc-*.pool.limit)
10951         local max=0
10952         for l in $limit; do
10953                 if [[ $l -gt $max ]]; then
10954                         max=$l
10955                 fi
10956         done
10957         echo $max
10958 }
10959
10960 test_124b() {
10961         [ $PARALLEL == "yes" ] && skip "skip parallel run"
10962         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
10963                 skip_env "no lru resize on server"
10964
10965         LIMIT=$(get_max_pool_limit)
10966
10967         NR=$(($(default_lru_size)*20))
10968         if [[ $NR -gt $LIMIT ]]; then
10969                 log "Limit lock number by $LIMIT locks"
10970                 NR=$LIMIT
10971         fi
10972
10973         IFree=$(mdsrate_inodes_available)
10974         if [ $IFree -lt $NR ]; then
10975                 log "Limit lock number by $IFree inodes"
10976                 NR=$IFree
10977         fi
10978
10979         lru_resize_disable mdc
10980         test_mkdir -p $DIR/$tdir/disable_lru_resize
10981
10982         createmany -o $DIR/$tdir/disable_lru_resize/f $NR
10983         log "doing ls -la $DIR/$tdir/disable_lru_resize 3 times"
10984         cancel_lru_locks mdc
10985         stime=`date +%s`
10986         PID=""
10987         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10988         PID="$PID $!"
10989         sleep 2
10990         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10991         PID="$PID $!"
10992         sleep 2
10993         ls -la $DIR/$tdir/disable_lru_resize > /dev/null &
10994         PID="$PID $!"
10995         wait $PID
10996         etime=`date +%s`
10997         nolruresize_delta=$((etime-stime))
10998         log "ls -la time: $nolruresize_delta seconds"
10999         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11000         unlinkmany $DIR/$tdir/disable_lru_resize/f $NR
11001
11002         lru_resize_enable mdc
11003         test_mkdir -p $DIR/$tdir/enable_lru_resize
11004
11005         createmany -o $DIR/$tdir/enable_lru_resize/f $NR
11006         log "doing ls -la $DIR/$tdir/enable_lru_resize 3 times"
11007         cancel_lru_locks mdc
11008         stime=`date +%s`
11009         PID=""
11010         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11011         PID="$PID $!"
11012         sleep 2
11013         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11014         PID="$PID $!"
11015         sleep 2
11016         ls -la $DIR/$tdir/enable_lru_resize > /dev/null &
11017         PID="$PID $!"
11018         wait $PID
11019         etime=`date +%s`
11020         lruresize_delta=$((etime-stime))
11021         log "ls -la time: $lruresize_delta seconds"
11022         log "lru_size = $(lctl get_param -n ldlm.namespaces.*mdc*.lru_size)"
11023
11024         if [ $lruresize_delta -gt $nolruresize_delta ]; then
11025                 log "ls -la is $(((lruresize_delta - $nolruresize_delta) * 100 / $nolruresize_delta))% slower with lru resize enabled"
11026         elif [ $nolruresize_delta -gt $lruresize_delta ]; then
11027                 log "ls -la is $(((nolruresize_delta - $lruresize_delta) * 100 / $nolruresize_delta))% faster with lru resize enabled"
11028         else
11029                 log "lru resize performs the same with no lru resize"
11030         fi
11031         unlinkmany $DIR/$tdir/enable_lru_resize/f $NR
11032 }
11033 run_test 124b "lru resize (performance test) ======================="
11034
11035 test_124c() {
11036         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11037         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11038                 skip_env "no lru resize on server"
11039
11040         # cache ununsed locks on client
11041         local nr=100
11042         cancel_lru_locks mdc
11043         test_mkdir $DIR/$tdir
11044         createmany -o $DIR/$tdir/f $nr ||
11045                 error "failed to create $nr files in $DIR/$tdir"
11046         ls -l $DIR/$tdir > /dev/null
11047
11048         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11049         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11050         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11051         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11052         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11053
11054         # set lru_max_age to 1 sec
11055         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11056         echo "sleep $((recalc_p * 2)) seconds..."
11057         sleep $((recalc_p * 2))
11058
11059         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11060         # restore lru_max_age
11061         $LCTL set_param -n $nsdir.lru_max_age $max_age
11062         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11063         unlinkmany $DIR/$tdir/f $nr
11064 }
11065 run_test 124c "LRUR cancel very aged locks"
11066
11067 test_124d() {
11068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11069         $LCTL get_param -n mdc.*.connect_flags | grep -q lru_resize ||
11070                 skip_env "no lru resize on server"
11071
11072         # cache ununsed locks on client
11073         local nr=100
11074
11075         lru_resize_disable mdc
11076         stack_trap "lru_resize_enable mdc" EXIT
11077
11078         cancel_lru_locks mdc
11079
11080         # asynchronous object destroy at MDT could cause bl ast to client
11081         test_mkdir $DIR/$tdir
11082         createmany -o $DIR/$tdir/f $nr ||
11083                 error "failed to create $nr files in $DIR/$tdir"
11084         stack_trap "unlinkmany $DIR/$tdir/f $nr" EXIT
11085
11086         ls -l $DIR/$tdir > /dev/null
11087
11088         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
11089         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
11090         local max_age=$($LCTL get_param -n $nsdir.lru_max_age)
11091         local recalc_p=$($LCTL get_param -n $nsdir.pool.recalc_period)
11092
11093         echo "unused=$unused, max_age=$max_age, recalc_p=$recalc_p"
11094
11095         # set lru_max_age to 1 sec
11096         $LCTL set_param $nsdir.lru_max_age=1000 # milliseconds
11097         stack_trap "$LCTL set_param -n $nsdir.lru_max_age $max_age" EXIT
11098
11099         echo "sleep $((recalc_p * 2)) seconds..."
11100         sleep $((recalc_p * 2))
11101
11102         local remaining=$($LCTL get_param -n $nsdir.lock_unused_count)
11103
11104         [ $remaining -eq 0 ] || error "$remaining locks are not canceled"
11105 }
11106 run_test 124d "cancel very aged locks if lru-resize diasbaled"
11107
11108 test_125() { # 13358
11109         $LCTL get_param -n llite.*.client_type | grep -q local ||
11110                 skip "must run as local client"
11111         $LCTL get_param -n mdc.*-mdc-*.connect_flags | grep -q acl ||
11112                 skip_env "must have acl enabled"
11113         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
11114
11115         test_mkdir $DIR/$tdir
11116         $LFS setstripe -S 65536 -c -1 $DIR/$tdir || error "setstripe failed"
11117         setfacl -R -m u:bin:rwx $DIR/$tdir || error "setfacl $DIR/$tdir failed"
11118         ls -ld $DIR/$tdir || error "cannot access $DIR/$tdir"
11119 }
11120 run_test 125 "don't return EPROTO when a dir has a non-default striping and ACLs"
11121
11122 test_126() { # bug 12829/13455
11123         $GSS && skip_env "must run as gss disabled"
11124         $LCTL get_param -n llite.*.client_type | grep -q local ||
11125                 skip "must run as local client"
11126         [ "$UID" != 0 ] && skip "must run as root, not UID $UID"
11127
11128         $RUNAS -u 0 -g 1 touch $DIR/$tfile || error "touch failed"
11129         gid=`ls -n $DIR/$tfile | awk '{print $4}'`
11130         rm -f $DIR/$tfile
11131         [ $gid -eq "1" ] || error "gid is set to" $gid "instead of 1"
11132 }
11133 run_test 126 "check that the fsgid provided by the client is taken into account"
11134
11135 test_127a() { # bug 15521
11136         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11137
11138         $LFS setstripe -i 0 -c 1 $DIR/$tfile || error "setstripe failed"
11139         $LCTL set_param osc.*.stats=0
11140         FSIZE=$((2048 * 1024))
11141         dd if=/dev/zero of=$DIR/$tfile bs=$FSIZE count=1
11142         cancel_lru_locks osc
11143         dd if=$DIR/$tfile of=/dev/null bs=$FSIZE
11144
11145         $LCTL get_param osc.*0000-osc-*.stats | grep samples > $DIR/${tfile}.tmp
11146         while read NAME COUNT SAMP UNIT MIN MAX SUM SUMSQ; do
11147                 echo "got $COUNT $NAME"
11148                 [ ! $MIN ] && error "Missing min value for $NAME proc entry"
11149                 eval $NAME=$COUNT || error "Wrong proc format"
11150
11151                 case $NAME in
11152                         read_bytes|write_bytes)
11153                         [ $MIN -lt 4096 ] && error "min is too small: $MIN"
11154                         [ $MIN -gt $FSIZE ] && error "min is too big: $MIN"
11155                         [ $MAX -lt 4096 ] && error "max is too small: $MAX"
11156                         [ $MAX -gt $FSIZE ] && error "max is too big: $MAX"
11157                         [ $SUM -ne $FSIZE ] && error "sum is wrong: $SUM"
11158                         [ $SUMSQ -lt $(((FSIZE /4096) * (4096 * 4096))) ] &&
11159                                 error "sumsquare is too small: $SUMSQ"
11160                         [ $SUMSQ -gt $((FSIZE * FSIZE)) ] &&
11161                                 error "sumsquare is too big: $SUMSQ"
11162                         ;;
11163                         *) ;;
11164                 esac
11165         done < $DIR/${tfile}.tmp
11166
11167         #check that we actually got some stats
11168         [ "$read_bytes" ] || error "Missing read_bytes stats"
11169         [ "$write_bytes" ] || error "Missing write_bytes stats"
11170         [ "$read_bytes" != 0 ] || error "no read done"
11171         [ "$write_bytes" != 0 ] || error "no write done"
11172 }
11173 run_test 127a "verify the client stats are sane"
11174
11175 test_127b() { # bug LU-333
11176         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11177         local name count samp unit min max sum sumsq
11178
11179         $LCTL set_param llite.*.stats=0
11180
11181         # perform 2 reads and writes so MAX is different from SUM.
11182         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11183         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1
11184         cancel_lru_locks osc
11185         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11186         dd if=$DIR/$tfile of=/dev/null bs=$PAGE_SIZE count=1
11187
11188         $LCTL get_param llite.*.stats | grep samples > $TMP/$tfile.tmp
11189         while read name count samp unit min max sum sumsq; do
11190                 echo "got $count $name"
11191                 eval $name=$count || error "Wrong proc format"
11192
11193                 case $name in
11194                 read_bytes)
11195                         [ $count -ne 2 ] && error "count is not 2: $count"
11196                         [ $min -ne $PAGE_SIZE ] &&
11197                                 error "min is not $PAGE_SIZE: $min"
11198                         [ $max -ne $PAGE_SIZE ] &&
11199                                 error "max is incorrect: $max"
11200                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11201                                 error "sum is wrong: $sum"
11202                         ;;
11203                 write_bytes)
11204                         [ $count -ne 2 ] && error "count is not 2: $count"
11205                         [ $min -ne $PAGE_SIZE ] &&
11206                                 error "min is not $PAGE_SIZE: $min"
11207                         [ $max -ne $PAGE_SIZE ] &&
11208                                 error "max is incorrect: $max"
11209                         [ $sum -ne $((PAGE_SIZE * 2)) ] &&
11210                                 error "sum is wrong: $sum"
11211                         ;;
11212                 *) ;;
11213                 esac
11214         done < $TMP/$tfile.tmp
11215
11216         #check that we actually got some stats
11217         [ "$read_bytes" ] || error "Missing read_bytes stats"
11218         [ "$write_bytes" ] || error "Missing write_bytes stats"
11219         [ "$read_bytes" != 0 ] || error "no read done"
11220         [ "$write_bytes" != 0 ] || error "no write done"
11221
11222         rm -f $TMP/${tfile}.tmp
11223 }
11224 run_test 127b "verify the llite client stats are sane"
11225
11226 test_127c() { # LU-12394
11227         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11228         local size
11229         local bsize
11230         local reads
11231         local writes
11232         local count
11233
11234         $LCTL set_param llite.*.extents_stats=1
11235         stack_trap "$LCTL set_param llite.*.extents_stats=0" EXIT
11236
11237         # Use two stripes so there is enough space in default config
11238         $LFS setstripe -c 2 $DIR/$tfile
11239
11240         # Extent stats start at 0-4K and go in power of two buckets
11241         # LL_HIST_START = 12 --> 2^12 = 4K
11242         # We do 3K*2^i, so 3K, 6K, 12K, 24K... hitting each bucket.
11243         # We do not do buckets larger than 64 MiB to avoid ENOSPC issues on
11244         # small configs
11245         for size in 3K 6K 12K 24K 48K 96K 192K 384K 768K 1536K 3M 6M 12M 24M 48M;
11246                 do
11247                 # Write and read, 2x each, second time at a non-zero offset
11248                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1
11249                 dd if=/dev/zero of=$DIR/$tfile bs=$size count=1 seek=10
11250                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1
11251                 dd if=$DIR/$tfile of=/dev/null bs=$size count=1 seek=10
11252                 rm -f $DIR/$tfile
11253         done
11254
11255         $LCTL get_param llite.*.extents_stats
11256
11257         count=2
11258         for bsize in 4K 8K 16K 32K 64K 128K 256K 512K 1M 2M 4M 8M 16M 32M 64M;
11259                 do
11260                 local bucket=$($LCTL get_param -n llite.*.extents_stats |
11261                                 grep -m 1 $bsize)
11262                 reads=$(echo $bucket | awk '{print $5}')
11263                 writes=$(echo $bucket | awk '{print $9}')
11264                 [ "$reads" -eq $count ] ||
11265                         error "$reads reads in < $bsize bucket, expect $count"
11266                 [ "$writes" -eq $count ] ||
11267                         error "$writes writes in < $bsize bucket, expect $count"
11268         done
11269
11270         # Test mmap write and read
11271         $LCTL set_param llite.*.extents_stats=c
11272         size=512
11273         dd if=/dev/zero of=$DIR/$tfile bs=${size}K count=1
11274         $MULTIOP $DIR/$tfile OSMRUc || error "$MULTIOP $DIR/$tfile failed"
11275         $MULTIOP $DIR/$tfile OSMWUc || error "$MULTIOP $DIR/$tfile failed"
11276
11277         $LCTL get_param llite.*.extents_stats
11278
11279         count=$(((size*1024) / PAGE_SIZE))
11280
11281         bsize=$((2 * PAGE_SIZE / 1024))K
11282
11283         bucket=$($LCTL get_param -n llite.*.extents_stats |
11284                         grep -m 1 $bsize)
11285         reads=$(echo $bucket | awk '{print $5}')
11286         writes=$(echo $bucket | awk '{print $9}')
11287         # mmap writes fault in the page first, creating an additonal read
11288         [ "$reads" -eq $((2 * count)) ] ||
11289                 error "$reads reads in < $bsize bucket, expect $count"
11290         [ "$writes" -eq $count ] ||
11291                 error "$writes writes in < $bsize bucket, expect $count"
11292 }
11293 run_test 127c "test llite extent stats with regular & mmap i/o"
11294
11295 test_128() { # bug 15212
11296         touch $DIR/$tfile
11297         $LFS 2>&1 <<-EOF | tee $TMP/$tfile.log
11298                 find $DIR/$tfile
11299                 find $DIR/$tfile
11300         EOF
11301
11302         result=$(grep error $TMP/$tfile.log)
11303         rm -f $DIR/$tfile $TMP/$tfile.log
11304         [ -z "$result" ] ||
11305                 error "consecutive find's under interactive lfs failed"
11306 }
11307 run_test 128 "interactive lfs for 2 consecutive find's"
11308
11309 set_dir_limits () {
11310         local mntdev
11311         local canondev
11312         local node
11313
11314         local ldproc=/proc/fs/ldiskfs
11315         local facets=$(get_facets MDS)
11316
11317         for facet in ${facets//,/ }; do
11318                 canondev=$(ldiskfs_canon \
11319                            *.$(convert_facet2label $facet).mntdev $facet)
11320                 do_facet $facet "test -e $ldproc/$canondev/max_dir_size" ||
11321                         ldproc=/sys/fs/ldiskfs
11322                 do_facet $facet "echo $1 >$ldproc/$canondev/max_dir_size"
11323                 do_facet $facet "echo $2 >$ldproc/$canondev/warning_dir_size"
11324         done
11325 }
11326
11327 check_mds_dmesg() {
11328         local facets=$(get_facets MDS)
11329         for facet in ${facets//,/ }; do
11330                 do_facet $facet "dmesg | tail -3 | grep -q $1" && return 0
11331         done
11332         return 1
11333 }
11334
11335 test_129() {
11336         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11337         [[ $MDS1_VERSION -ge $(version_code 2.5.56) ]] ||
11338                 skip "Need MDS version with at least 2.5.56"
11339         if [ "$mds1_FSTYPE" != ldiskfs ]; then
11340                 skip_env "ldiskfs only test"
11341         fi
11342         remote_mds_nodsh && skip "remote MDS with nodsh"
11343
11344         local ENOSPC=28
11345         local EFBIG=27
11346         local has_warning=false
11347
11348         rm -rf $DIR/$tdir
11349         mkdir -p $DIR/$tdir
11350
11351         # block size of mds1
11352         local maxsize=$(($($LCTL get_param -n mdc.*MDT0000*.blocksize) * 5))
11353         set_dir_limits $maxsize $maxsize
11354         local dirsize=$(stat -c%s "$DIR/$tdir")
11355         local nfiles=0
11356         while [[ $dirsize -le $maxsize ]]; do
11357                 $MULTIOP $DIR/$tdir/file_base_$nfiles Oc
11358                 rc=$?
11359                 if ! $has_warning; then
11360                         check_mds_dmesg '"is approaching"' && has_warning=true
11361                 fi
11362                 # check two errors:
11363                 # ENOSPC for new ext4 max_dir_size (kernel commit df981d03ee)
11364                 # EFBIG for previous versions included in ldiskfs series
11365                 if [ $rc -eq $EFBIG ] || [ $rc -eq $ENOSPC ]; then
11366                         set_dir_limits 0 0
11367                         echo "return code $rc received as expected"
11368
11369                         createmany -o $DIR/$tdir/file_extra_$nfiles. 5 ||
11370                                 error_exit "create failed w/o dir size limit"
11371
11372                         check_mds_dmesg '"has reached"' ||
11373                                 error_exit "reached message should be output"
11374
11375                         [ $has_warning = "false" ] &&
11376                                 error_exit "warning message should be output"
11377
11378                         dirsize=$(stat -c%s "$DIR/$tdir")
11379
11380                         [[ $dirsize -ge $maxsize ]] && return 0
11381                         error_exit "current dir size $dirsize, " \
11382                                    "previous limit $maxsize"
11383                 elif [ $rc -ne 0 ]; then
11384                         set_dir_limits 0 0
11385                         error_exit "return $rc received instead of expected " \
11386                                    "$EFBIG or $ENOSPC, files in dir $dirsize"
11387                 fi
11388                 nfiles=$((nfiles + 1))
11389                 dirsize=$(stat -c%s "$DIR/$tdir")
11390         done
11391
11392         set_dir_limits 0 0
11393         error "exceeded dir size limit $maxsize($MDSCOUNT) : $dirsize bytes"
11394 }
11395 run_test 129 "test directory size limit ========================"
11396
11397 OLDIFS="$IFS"
11398 cleanup_130() {
11399         trap 0
11400         IFS="$OLDIFS"
11401 }
11402
11403 test_130a() {
11404         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11405         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11406
11407         trap cleanup_130 EXIT RETURN
11408
11409         local fm_file=$DIR/$tfile
11410         $LFS setstripe -S 65536 -c 1 $fm_file || error "setstripe on $fm_file"
11411         dd if=/dev/zero of=$fm_file bs=65536 count=1 ||
11412                 error "dd failed for $fm_file"
11413
11414         # LU-1795: test filefrag/FIEMAP once, even if unsupported
11415         filefrag -ves $fm_file
11416         RC=$?
11417         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11418                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11419         [ $RC != 0 ] && error "filefrag $fm_file failed"
11420
11421         filefrag_op=$(filefrag -ve -k $fm_file |
11422                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11423         lun=$($LFS getstripe -i $fm_file)
11424
11425         start_blk=`echo $filefrag_op | cut -d: -f2 | cut -d. -f1`
11426         IFS=$'\n'
11427         tot_len=0
11428         for line in $filefrag_op
11429         do
11430                 frag_lun=`echo $line | cut -d: -f5`
11431                 ext_len=`echo $line | cut -d: -f4`
11432                 if (( $frag_lun != $lun )); then
11433                         cleanup_130
11434                         error "FIEMAP on 1-stripe file($fm_file) failed"
11435                         return
11436                 fi
11437                 (( tot_len += ext_len ))
11438         done
11439
11440         if (( lun != frag_lun || start_blk != 0 || tot_len != 64 )); then
11441                 cleanup_130
11442                 error "FIEMAP on 1-stripe file($fm_file) failed;"
11443                 return
11444         fi
11445
11446         cleanup_130
11447
11448         echo "FIEMAP on single striped file succeeded"
11449 }
11450 run_test 130a "FIEMAP (1-stripe file)"
11451
11452 test_130b() {
11453         [ "$OSTCOUNT" -lt "2" ] && skip_env "needs >= 2 OSTs"
11454
11455         local filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11456         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11457
11458         trap cleanup_130 EXIT RETURN
11459
11460         local fm_file=$DIR/$tfile
11461         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11462                         error "setstripe on $fm_file"
11463         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11464                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11465
11466         dd if=/dev/zero of=$fm_file bs=1M count=$OSTCOUNT ||
11467                 error "dd failed on $fm_file"
11468
11469         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11470         filefrag_op=$(filefrag -ve -k $fm_file |
11471                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11472
11473         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11474                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11475
11476         IFS=$'\n'
11477         tot_len=0
11478         num_luns=1
11479         for line in $filefrag_op
11480         do
11481                 frag_lun=$(echo $line | cut -d: -f5 |
11482                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11483                 ext_len=$(echo $line | cut -d: -f4)
11484                 if (( $frag_lun != $last_lun )); then
11485                         if (( tot_len != 1024 )); then
11486                                 cleanup_130
11487                                 error "FIEMAP on $fm_file failed; returned " \
11488                                 "len $tot_len for OST $last_lun instead of 1024"
11489                                 return
11490                         else
11491                                 (( num_luns += 1 ))
11492                                 tot_len=0
11493                         fi
11494                 fi
11495                 (( tot_len += ext_len ))
11496                 last_lun=$frag_lun
11497         done
11498         if (( num_luns != $OSTCOUNT || tot_len != 1024 )); then
11499                 cleanup_130
11500                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11501                         "luns or wrong len for OST $last_lun"
11502                 return
11503         fi
11504
11505         cleanup_130
11506
11507         echo "FIEMAP on $OSTCOUNT-stripe file succeeded"
11508 }
11509 run_test 130b "FIEMAP ($OSTCOUNT-stripe file)"
11510
11511 test_130c() {
11512         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11513
11514         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11515         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11516
11517         trap cleanup_130 EXIT RETURN
11518
11519         local fm_file=$DIR/$tfile
11520         $LFS setstripe -S 65536 -c 2 $fm_file || error "setstripe on $fm_file"
11521         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11522                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11523
11524         dd if=/dev/zero of=$fm_file seek=1 bs=1M count=1 ||
11525                         error "dd failed on $fm_file"
11526
11527         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11528         filefrag_op=$(filefrag -ve -k $fm_file |
11529                 sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11530
11531         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11532                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11533
11534         IFS=$'\n'
11535         tot_len=0
11536         num_luns=1
11537         for line in $filefrag_op
11538         do
11539                 frag_lun=$(echo $line | cut -d: -f5 |
11540                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11541                 ext_len=$(echo $line | cut -d: -f4)
11542                 if (( $frag_lun != $last_lun )); then
11543                         logical=`echo $line | cut -d: -f2 | cut -d. -f1`
11544                         if (( logical != 512 )); then
11545                                 cleanup_130
11546                                 error "FIEMAP on $fm_file failed; returned " \
11547                                 "logical start for lun $logical instead of 512"
11548                                 return
11549                         fi
11550                         if (( tot_len != 512 )); then
11551                                 cleanup_130
11552                                 error "FIEMAP on $fm_file failed; returned " \
11553                                 "len $tot_len for OST $last_lun instead of 1024"
11554                                 return
11555                         else
11556                                 (( num_luns += 1 ))
11557                                 tot_len=0
11558                         fi
11559                 fi
11560                 (( tot_len += ext_len ))
11561                 last_lun=$frag_lun
11562         done
11563         if (( num_luns != 2 || tot_len != 512 )); then
11564                 cleanup_130
11565                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11566                         "luns or wrong len for OST $last_lun"
11567                 return
11568         fi
11569
11570         cleanup_130
11571
11572         echo "FIEMAP on 2-stripe file with hole succeeded"
11573 }
11574 run_test 130c "FIEMAP (2-stripe file with hole)"
11575
11576 test_130d() {
11577         [[ $OSTCOUNT -lt 3 ]] && skip_env "needs >= 3 OSTs"
11578
11579         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11580         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11581
11582         trap cleanup_130 EXIT RETURN
11583
11584         local fm_file=$DIR/$tfile
11585         $LFS setstripe -S 65536 -c $OSTCOUNT $fm_file ||
11586                         error "setstripe on $fm_file"
11587         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11588                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11589
11590         local actual_stripe_count=$($LFS getstripe -c $fm_file)
11591         dd if=/dev/zero of=$fm_file bs=1M count=$actual_stripe_count ||
11592                 error "dd failed on $fm_file"
11593
11594         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11595         filefrag_op=$(filefrag -ve -k $fm_file |
11596                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11597
11598         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11599                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11600
11601         IFS=$'\n'
11602         tot_len=0
11603         num_luns=1
11604         for line in $filefrag_op
11605         do
11606                 frag_lun=$(echo $line | cut -d: -f5 |
11607                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11608                 ext_len=$(echo $line | cut -d: -f4)
11609                 if (( $frag_lun != $last_lun )); then
11610                         if (( tot_len != 1024 )); then
11611                                 cleanup_130
11612                                 error "FIEMAP on $fm_file failed; returned " \
11613                                 "len $tot_len for OST $last_lun instead of 1024"
11614                                 return
11615                         else
11616                                 (( num_luns += 1 ))
11617                                 tot_len=0
11618                         fi
11619                 fi
11620                 (( tot_len += ext_len ))
11621                 last_lun=$frag_lun
11622         done
11623         if (( num_luns != actual_stripe_count || tot_len != 1024 )); then
11624                 cleanup_130
11625                 error "FIEMAP on $fm_file failed; returned wrong number of " \
11626                         "luns or wrong len for OST $last_lun"
11627                 return
11628         fi
11629
11630         cleanup_130
11631
11632         echo "FIEMAP on N-stripe file succeeded"
11633 }
11634 run_test 130d "FIEMAP (N-stripe file)"
11635
11636 test_130e() {
11637         [[ $OSTCOUNT -lt 2 ]] && skip_env "needs >= 2 OSTs"
11638
11639         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11640         [ -n "$filefrag_op" ] && skip_env "filefrag does not support FIEMAP"
11641
11642         trap cleanup_130 EXIT RETURN
11643
11644         local fm_file=$DIR/$tfile
11645         $LFS setstripe -S 131072 -c 2 $fm_file || error "setstripe on $fm_file"
11646         [ "$(facet_fstype ost$(($($LFS getstripe -i $fm_file) + 1)))" = "zfs" ] &&
11647                 skip_env "ORI-366/LU-1941: FIEMAP unimplemented on ZFS"
11648
11649         NUM_BLKS=512
11650         EXPECTED_LEN=$(( (NUM_BLKS / 2) * 64 ))
11651         for ((i = 0; i < $NUM_BLKS; i++))
11652         do
11653                 dd if=/dev/zero of=$fm_file count=1 bs=64k seek=$((2*$i)) conv=notrunc > /dev/null 2>&1
11654         done
11655
11656         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11657         filefrag_op=$(filefrag -ve -k $fm_file |
11658                         sed -n '/ext:/,/found/{/ext:/d; /found/d; p}')
11659
11660         last_lun=$(echo $filefrag_op | cut -d: -f5 |
11661                 sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11662
11663         IFS=$'\n'
11664         tot_len=0
11665         num_luns=1
11666         for line in $filefrag_op
11667         do
11668                 frag_lun=$(echo $line | cut -d: -f5 |
11669                         sed -e 's/^[ \t]*/0x/' | sed -e 's/0x0x/0x/')
11670                 ext_len=$(echo $line | cut -d: -f4)
11671                 if (( $frag_lun != $last_lun )); then
11672                         if (( tot_len != $EXPECTED_LEN )); then
11673                                 cleanup_130
11674                                 error "FIEMAP on $fm_file failed; returned " \
11675                                 "len $tot_len for OST $last_lun instead " \
11676                                 "of $EXPECTED_LEN"
11677                                 return
11678                         else
11679                                 (( num_luns += 1 ))
11680                                 tot_len=0
11681                         fi
11682                 fi
11683                 (( tot_len += ext_len ))
11684                 last_lun=$frag_lun
11685         done
11686         if (( num_luns != 2 || tot_len != $EXPECTED_LEN )); then
11687                 cleanup_130
11688                 error "FIEMAP on $fm_file failed; returned wrong number " \
11689                         "of luns or wrong len for OST $last_lun"
11690                 return
11691         fi
11692
11693         cleanup_130
11694
11695         echo "FIEMAP with continuation calls succeeded"
11696 }
11697 run_test 130e "FIEMAP (test continuation FIEMAP calls)"
11698
11699 test_130f() {
11700         filefrag_op=$(filefrag -e 2>&1 | grep "invalid option")
11701         [ -n "$filefrag_op" ] && skip "filefrag does not support FIEMAP"
11702
11703         local fm_file=$DIR/$tfile
11704         $MULTIOP $fm_file oO_RDWR:O_CREAT:O_LOV_DELAY_CREATE:T33554432c ||
11705                 error "multiop create with lov_delay_create on $fm_file"
11706
11707         filefrag -ves $fm_file || error "filefrag $fm_file failed"
11708         filefrag_extents=$(filefrag -vek $fm_file |
11709                            awk '/extents? found/ { print $2 }')
11710         if [[ "$filefrag_extents" != "0" ]]; then
11711                 error "FIEMAP on $fm_file failed; " \
11712                       "returned $filefrag_extents expected 0"
11713         fi
11714
11715         rm -f $fm_file
11716 }
11717 run_test 130f "FIEMAP (unstriped file)"
11718
11719 # Test for writev/readv
11720 test_131a() {
11721         rwv -f $DIR/$tfile -w -n 3 524288 1048576 1572864 ||
11722                 error "writev test failed"
11723         rwv -f $DIR/$tfile -r -v -n 2 1572864 1048576 ||
11724                 error "readv failed"
11725         rm -f $DIR/$tfile
11726 }
11727 run_test 131a "test iov's crossing stripe boundary for writev/readv"
11728
11729 test_131b() {
11730         local fsize=$((524288 + 1048576 + 1572864))
11731         rwv -f $DIR/$tfile -w -a -n 3 524288 1048576 1572864 &&
11732                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11733                         error "append writev test failed"
11734
11735         ((fsize += 1572864 + 1048576))
11736         rwv -f $DIR/$tfile -w -a -n 2 1572864 1048576 &&
11737                 $CHECKSTAT -t file $DIR/$tfile -s $fsize ||
11738                         error "append writev test failed"
11739         rm -f $DIR/$tfile
11740 }
11741 run_test 131b "test append writev"
11742
11743 test_131c() {
11744         rwv -f $DIR/$tfile -w -d -n 1 1048576 || return 0
11745         error "NOT PASS"
11746 }
11747 run_test 131c "test read/write on file w/o objects"
11748
11749 test_131d() {
11750         rwv -f $DIR/$tfile -w -n 1 1572864
11751         NOB=`rwv -f $DIR/$tfile -r -n 3 524288 524288 1048576 | awk '/error/ {print $6}'`
11752         if [ "$NOB" != 1572864 ]; then
11753                 error "Short read filed: read $NOB bytes instead of 1572864"
11754         fi
11755         rm -f $DIR/$tfile
11756 }
11757 run_test 131d "test short read"
11758
11759 test_131e() {
11760         rwv -f $DIR/$tfile -w -s 1048576 -n 1 1048576
11761         rwv -f $DIR/$tfile -r -z -s 0 -n 1 524288 || \
11762         error "read hitting hole failed"
11763         rm -f $DIR/$tfile
11764 }
11765 run_test 131e "test read hitting hole"
11766
11767 check_stats() {
11768         local facet=$1
11769         local op=$2
11770         local want=${3:-0}
11771         local res
11772
11773         case $facet in
11774         mds*) res=$(do_facet $facet \
11775                    $LCTL get_param mdt.$FSNAME-MDT0000.md_stats | grep "$op")
11776                  ;;
11777         ost*) res=$(do_facet $facet \
11778                    $LCTL get_param obdfilter.$FSNAME-OST0000.stats | grep "$op")
11779                  ;;
11780         *) error "Wrong facet '$facet'" ;;
11781         esac
11782         [ "$res" ] || error "The counter for $op on $facet was not incremented"
11783         # if the argument $3 is zero, it means any stat increment is ok.
11784         if [[ $want -gt 0 ]]; then
11785                 local count=$(echo $res | awk '{ print $2 }')
11786                 [[ $count -ne $want ]] &&
11787                         error "The $op counter on $facet is $count, not $want"
11788         fi
11789 }
11790
11791 test_133a() {
11792         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11793         remote_ost_nodsh && skip "remote OST with nodsh"
11794         remote_mds_nodsh && skip "remote MDS with nodsh"
11795         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11796                 skip_env "MDS doesn't support rename stats"
11797
11798         local testdir=$DIR/${tdir}/stats_testdir
11799
11800         mkdir -p $DIR/${tdir}
11801
11802         # clear stats.
11803         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11804         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11805
11806         # verify mdt stats first.
11807         mkdir ${testdir} || error "mkdir failed"
11808         check_stats $SINGLEMDS "mkdir" 1
11809         touch ${testdir}/${tfile} || error "touch failed"
11810         check_stats $SINGLEMDS "open" 1
11811         check_stats $SINGLEMDS "close" 1
11812         [ $MDS1_VERSION -ge $(version_code 2.8.54) ] && {
11813                 mknod ${testdir}/${tfile}-pipe p || error "mknod failed"
11814                 check_stats $SINGLEMDS "mknod" 2
11815         }
11816         rm -f ${testdir}/${tfile}-pipe || error "pipe remove failed"
11817         check_stats $SINGLEMDS "unlink" 1
11818         rm -f ${testdir}/${tfile} || error "file remove failed"
11819         check_stats $SINGLEMDS "unlink" 2
11820
11821         # remove working dir and check mdt stats again.
11822         rmdir ${testdir} || error "rmdir failed"
11823         check_stats $SINGLEMDS "rmdir" 1
11824
11825         local testdir1=$DIR/${tdir}/stats_testdir1
11826         mkdir -p ${testdir}
11827         mkdir -p ${testdir1}
11828         touch ${testdir1}/test1
11829         mv ${testdir1}/test1 ${testdir} || error "file crossdir rename"
11830         check_stats $SINGLEMDS "crossdir_rename" 1
11831
11832         mv ${testdir}/test1 ${testdir}/test0 || error "file samedir rename"
11833         check_stats $SINGLEMDS "samedir_rename" 1
11834
11835         rm -rf $DIR/${tdir}
11836 }
11837 run_test 133a "Verifying MDT stats ========================================"
11838
11839 test_133b() {
11840         local res
11841
11842         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11843         remote_ost_nodsh && skip "remote OST with nodsh"
11844         remote_mds_nodsh && skip "remote MDS with nodsh"
11845
11846         local testdir=$DIR/${tdir}/stats_testdir
11847
11848         mkdir -p ${testdir} || error "mkdir failed"
11849         touch ${testdir}/${tfile} || error "touch failed"
11850         cancel_lru_locks mdc
11851
11852         # clear stats.
11853         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11854         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11855
11856         # extra mdt stats verification.
11857         chmod 444 ${testdir}/${tfile} || error "chmod failed"
11858         check_stats $SINGLEMDS "setattr" 1
11859         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11860         if [ $MDS1_VERSION -ne $(version_code 2.2.0) ]
11861         then            # LU-1740
11862                 ls -l ${testdir}/${tfile} > /dev/null|| error "ls failed"
11863                 check_stats $SINGLEMDS "getattr" 1
11864         fi
11865         rm -rf $DIR/${tdir}
11866
11867         # when DNE is enabled, MDT uses STATFS RPC to ping other targets
11868         # so the check below is not reliable
11869         [ $MDSCOUNT -eq 1 ] || return 0
11870
11871         # Sleep to avoid a cached response.
11872         #define OBD_STATFS_CACHE_SECONDS 1
11873         sleep 2
11874         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11875         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11876         $LFS df || error "lfs failed"
11877         check_stats $SINGLEMDS "statfs" 1
11878
11879         # check aggregated statfs (LU-10018)
11880         [ $MDS1_VERSION -lt $(version_code 2.11.54) ] &&
11881                 return 0
11882         [ $CLIENT_VERSION -lt $(version_code 2.11.54) ] &&
11883                 return 0
11884         sleep 2
11885         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11886         do_facet ost1 $LCTL set_param obdfilter.*.exports.*.stats=clear
11887         df $DIR
11888         check_stats $SINGLEMDS "statfs" 1
11889
11890         # We want to check that the client didn't send OST_STATFS to
11891         # ost1 but the MDT also uses OST_STATFS for precreate. So some
11892         # extra care is needed here.
11893         if remote_mds; then
11894                 local nid=$($LCTL list_nids | head -1 | sed  "s/\./\\\./g")
11895                 local param="obdfilter.$FSNAME-OST0000.exports.'$nid'.stats"
11896
11897                 res=$(do_facet ost1 $LCTL get_param $param | grep statfs)
11898                 [ "$res" ] && error "OST got STATFS"
11899         fi
11900
11901         return 0
11902 }
11903 run_test 133b "Verifying extra MDT stats =================================="
11904
11905 test_133c() {
11906         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11907         remote_ost_nodsh && skip "remote OST with nodsh"
11908         remote_mds_nodsh && skip "remote MDS with nodsh"
11909
11910         local testdir=$DIR/$tdir/stats_testdir
11911
11912         test_mkdir -p $testdir
11913
11914         # verify obdfilter stats.
11915         $LFS setstripe -c 1 -i 0 $testdir/$tfile
11916         sync
11917         cancel_lru_locks osc
11918         wait_delete_completed
11919
11920         # clear stats.
11921         do_facet $SINGLEMDS $LCTL set_param mdt.*.md_stats=clear
11922         do_facet ost1 $LCTL set_param obdfilter.*.stats=clear
11923
11924         dd if=/dev/zero of=$testdir/$tfile conv=notrunc bs=512k count=1 ||
11925                 error "dd failed"
11926         sync
11927         cancel_lru_locks osc
11928         check_stats ost1 "write" 1
11929
11930         dd if=$testdir/$tfile of=/dev/null bs=1k count=1 || error "dd failed"
11931         check_stats ost1 "read" 1
11932
11933         > $testdir/$tfile || error "truncate failed"
11934         check_stats ost1 "punch" 1
11935
11936         rm -f $testdir/$tfile || error "file remove failed"
11937         wait_delete_completed
11938         check_stats ost1 "destroy" 1
11939
11940         rm -rf $DIR/$tdir
11941 }
11942 run_test 133c "Verifying OST stats ========================================"
11943
11944 order_2() {
11945         local value=$1
11946         local orig=$value
11947         local order=1
11948
11949         while [ $value -ge 2 ]; do
11950                 order=$((order*2))
11951                 value=$((value/2))
11952         done
11953
11954         if [ $orig -gt $order ]; then
11955                 order=$((order*2))
11956         fi
11957         echo $order
11958 }
11959
11960 size_in_KMGT() {
11961     local value=$1
11962     local size=('K' 'M' 'G' 'T');
11963     local i=0
11964     local size_string=$value
11965
11966     while [ $value -ge 1024 ]; do
11967         if [ $i -gt 3 ]; then
11968             #T is the biggest unit we get here, if that is bigger,
11969             #just return XXXT
11970             size_string=${value}T
11971             break
11972         fi
11973         value=$((value >> 10))
11974         if [ $value -lt 1024 ]; then
11975             size_string=${value}${size[$i]}
11976             break
11977         fi
11978         i=$((i + 1))
11979     done
11980
11981     echo $size_string
11982 }
11983
11984 get_rename_size() {
11985         local size=$1
11986         local context=${2:-.}
11987         local sample=$(do_facet $SINGLEMDS $LCTL \
11988                 get_param mdt.$FSNAME-MDT0000.rename_stats |
11989                 grep -A1 $context |
11990                 awk '/ '${size}'/ {print $4}' | sed -e "s/,//g")
11991         echo $sample
11992 }
11993
11994 test_133d() {
11995         [ $PARALLEL == "yes" ] && skip "skip parallel run"
11996         remote_ost_nodsh && skip "remote OST with nodsh"
11997         remote_mds_nodsh && skip "remote MDS with nodsh"
11998         do_facet $SINGLEMDS $LCTL list_param mdt.*.rename_stats ||
11999                 skip_env "MDS doesn't support rename stats"
12000
12001         local testdir1=$DIR/${tdir}/stats_testdir1
12002         local testdir2=$DIR/${tdir}/stats_testdir2
12003         mkdir -p $DIR/${tdir}
12004
12005         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12006
12007         lfs mkdir -i 0 -c 1 ${testdir1} || error "mkdir failed"
12008         lfs mkdir -i 0 -c 1 ${testdir2} || error "mkdir failed"
12009
12010         createmany -o $testdir1/test 512 || error "createmany failed"
12011
12012         # check samedir rename size
12013         mv ${testdir1}/test0 ${testdir1}/test_0
12014
12015         local testdir1_size=$(ls -l $DIR/${tdir} |
12016                 awk '/stats_testdir1/ {print $5}')
12017         local testdir2_size=$(ls -l $DIR/${tdir} |
12018                 awk '/stats_testdir2/ {print $5}')
12019
12020         testdir1_size=$(order_2 $testdir1_size)
12021         testdir2_size=$(order_2 $testdir2_size)
12022
12023         testdir1_size=$(size_in_KMGT $testdir1_size)
12024         testdir2_size=$(size_in_KMGT $testdir2_size)
12025
12026         echo "source rename dir size: ${testdir1_size}"
12027         echo "target rename dir size: ${testdir2_size}"
12028
12029         local cmd="do_facet $SINGLEMDS $LCTL "
12030         cmd+="get_param mdt.$FSNAME-MDT0000.rename_stats"
12031
12032         eval $cmd || error "$cmd failed"
12033         local samedir=$($cmd | grep 'same_dir')
12034         local same_sample=$(get_rename_size $testdir1_size)
12035         [ -z "$samedir" ] && error "samedir_rename_size count error"
12036         [[ $same_sample -eq 1 ]] ||
12037                 error "samedir_rename_size error $same_sample"
12038         echo "Check same dir rename stats success"
12039
12040         do_facet $SINGLEMDS $LCTL set_param mdt.*.rename_stats=clear
12041
12042         # check crossdir rename size
12043         mv ${testdir1}/test_0 ${testdir2}/test_0
12044
12045         testdir1_size=$(ls -l $DIR/${tdir} |
12046                 awk '/stats_testdir1/ {print $5}')
12047         testdir2_size=$(ls -l $DIR/${tdir} |
12048                 awk '/stats_testdir2/ {print $5}')
12049
12050         testdir1_size=$(order_2 $testdir1_size)
12051         testdir2_size=$(order_2 $testdir2_size)
12052
12053         testdir1_size=$(size_in_KMGT $testdir1_size)
12054         testdir2_size=$(size_in_KMGT $testdir2_size)
12055
12056         echo "source rename dir size: ${testdir1_size}"
12057         echo "target rename dir size: ${testdir2_size}"
12058
12059         eval $cmd || error "$cmd failed"
12060         local crossdir=$($cmd | grep 'crossdir')
12061         local src_sample=$(get_rename_size $testdir1_size crossdir_src)
12062         local tgt_sample=$(get_rename_size $testdir2_size crossdir_tgt)
12063         [ -z "$crossdir" ] && error "crossdir_rename_size count error"
12064         [[ $src_sample -eq 1 ]] ||
12065                 error "crossdir_rename_size error $src_sample"
12066         [[ $tgt_sample -eq 1 ]] ||
12067                 error "crossdir_rename_size error $tgt_sample"
12068         echo "Check cross dir rename stats success"
12069         rm -rf $DIR/${tdir}
12070 }
12071 run_test 133d "Verifying rename_stats ========================================"
12072
12073 test_133e() {
12074         remote_mds_nodsh && skip "remote MDS with nodsh"
12075         remote_ost_nodsh && skip "remote OST with nodsh"
12076         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12077
12078         local testdir=$DIR/${tdir}/stats_testdir
12079         local ctr f0 f1 bs=32768 count=42 sum
12080
12081         mkdir -p ${testdir} || error "mkdir failed"
12082
12083         $LFS setstripe -c 1 -i 0 ${testdir}/${tfile}
12084
12085         for ctr in {write,read}_bytes; do
12086                 sync
12087                 cancel_lru_locks osc
12088
12089                 do_facet ost1 $LCTL set_param -n \
12090                         "obdfilter.*.exports.clear=clear"
12091
12092                 if [ $ctr = write_bytes ]; then
12093                         f0=/dev/zero
12094                         f1=${testdir}/${tfile}
12095                 else
12096                         f0=${testdir}/${tfile}
12097                         f1=/dev/null
12098                 fi
12099
12100                 dd if=$f0 of=$f1 conv=notrunc bs=$bs count=$count || \
12101                         error "dd failed"
12102                 sync
12103                 cancel_lru_locks osc
12104
12105                 sum=$(do_facet ost1 $LCTL get_param \
12106                         "obdfilter.*.exports.*.stats" |
12107                         awk -v ctr=$ctr 'BEGIN { sum = 0 }
12108                                 $1 == ctr { sum += $7 }
12109                                 END { printf("%0.0f", sum) }')
12110
12111                 if ((sum != bs * count)); then
12112                         error "Bad $ctr sum, expected $((bs * count)), got $sum"
12113                 fi
12114         done
12115
12116         rm -rf $DIR/${tdir}
12117 }
12118 run_test 133e "Verifying OST {read,write}_bytes nid stats ================="
12119
12120 proc_regexp="/{proc,sys}/{fs,sys,kernel/debug}/{lustre,lnet}/"
12121
12122 # Some versions of find (4.5.11, 4.5.14) included in CentOS 7.3-7.5 do
12123 # not honor the -ignore_readdir_race option correctly. So we call
12124 # error_ignore() rather than error() in these cases. See LU-11152.
12125 error_133() {
12126         if (find --version; do_facet mds1 find --version) |
12127                 grep -q '\b4\.5\.1[1-4]\b'; then
12128                 error_ignore LU-11152 "$@"
12129         else
12130                 error "$@"
12131         fi
12132 }
12133
12134 test_133f() {
12135         # First without trusting modes.
12136         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
12137         echo "proc_dirs='$proc_dirs'"
12138         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
12139         find $proc_dirs -exec cat '{}' \; &> /dev/null
12140
12141         # Second verifying readability.
12142         $LCTL get_param -R '*' &> /dev/null
12143
12144         # Verifing writability with badarea_io.
12145         find $proc_dirs \
12146                 -ignore_readdir_race \
12147                 -type f \
12148                 -not -name force_lbug \
12149                 -not -name changelog_mask \
12150                 -exec badarea_io '{}' \; ||
12151                         error_133 "find $proc_dirs failed"
12152 }
12153 run_test 133f "Check reads/writes of client lustre proc files with bad area io"
12154
12155 test_133g() {
12156         remote_mds_nodsh && skip "remote MDS with nodsh"
12157         remote_ost_nodsh && skip "remote OST with nodsh"
12158
12159         # eventually, this can also be replaced with "lctl get_param -R",
12160         # but not until that option is always available on the server
12161         local facet
12162         for facet in mds1 ost1; do
12163                 [ $(lustre_version_code $facet) -le $(version_code 2.5.54) ] &&
12164                         skip_noexit "Too old lustre on $facet"
12165                 local facet_proc_dirs=$(do_facet $facet \
12166                                         \\\ls -d $proc_regexp 2>/dev/null)
12167                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12168                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12169                 do_facet $facet find $facet_proc_dirs \
12170                         ! -name req_history \
12171                         -exec cat '{}' \\\; &> /dev/null
12172
12173                 do_facet $facet find $facet_proc_dirs \
12174                         ! -name req_history \
12175                         -type f \
12176                         -exec cat '{}' \\\; &> /dev/null ||
12177                                 error "proc file read failed"
12178
12179                 do_facet $facet find $facet_proc_dirs \
12180                         -ignore_readdir_race \
12181                         -type f \
12182                         -not -name force_lbug \
12183                         -not -name changelog_mask \
12184                         -exec badarea_io '{}' \\\; ||
12185                                 error_133 "$facet find $facet_proc_dirs failed"
12186         done
12187
12188         # remount the FS in case writes/reads /proc break the FS
12189         cleanup || error "failed to unmount"
12190         setup || error "failed to setup"
12191         true
12192 }
12193 run_test 133g "Check reads/writes of server lustre proc files with bad area io"
12194
12195 test_133h() {
12196         remote_mds_nodsh && skip "remote MDS with nodsh"
12197         remote_ost_nodsh && skip "remote OST with nodsh"
12198         [[ $MDS1_VERSION -lt $(version_code 2.9.54) ]] &&
12199                 skip "Need MDS version at least 2.9.54"
12200
12201         local facet
12202
12203         for facet in client mds1 ost1; do
12204                 local facet_proc_dirs=$(do_facet $facet \
12205                                         \\\ls -d $proc_regexp 2> /dev/null)
12206                 [ -z "$facet_proc_dirs" ] && error "no proc_dirs on $facet"
12207                 echo "${facet}_proc_dirs='$facet_proc_dirs'"
12208                 # Get the list of files that are missing the terminating newline
12209                 local missing=($(do_facet $facet \
12210                         find ${facet_proc_dirs} -type f \|              \
12211                                 while read F\; do                       \
12212                                         awk -v FS='\v' -v RS='\v\v'     \
12213                                         "'END { if(NR>0 &&              \
12214                                         \\\$NF !~ /.*\\\n\$/)           \
12215                                                 print FILENAME}'"       \
12216                                         '\$F'\;                         \
12217                                 done 2>/dev/null))
12218                 [ ${#missing[*]} -eq 0 ] ||
12219                         error "files do not end with newline: ${missing[*]}"
12220         done
12221 }
12222 run_test 133h "Proc files should end with newlines"
12223
12224 test_134a() {
12225         remote_mds_nodsh && skip "remote MDS with nodsh"
12226         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12227                 skip "Need MDS version at least 2.7.54"
12228
12229         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12230         cancel_lru_locks mdc
12231
12232         local nsdir="ldlm.namespaces.*-MDT0000-mdc-*"
12233         local unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12234         [ $unused -eq 0 ] || error "$unused locks are not cleared"
12235
12236         local nr=1000
12237         createmany -o $DIR/$tdir/f $nr ||
12238                 error "failed to create $nr files in $DIR/$tdir"
12239         unused=$($LCTL get_param -n $nsdir.lock_unused_count)
12240
12241         #define OBD_FAIL_LDLM_WATERMARK_LOW     0x327
12242         do_facet mds1 $LCTL set_param fail_loc=0x327
12243         do_facet mds1 $LCTL set_param fail_val=500
12244         touch $DIR/$tdir/m
12245
12246         echo "sleep 10 seconds ..."
12247         sleep 10
12248         local lck_cnt=$($LCTL get_param -n $nsdir.lock_unused_count)
12249
12250         do_facet mds1 $LCTL set_param fail_loc=0
12251         do_facet mds1 $LCTL set_param fail_val=0
12252         [ $lck_cnt -lt $unused ] ||
12253                 error "No locks reclaimed, before:$unused, after:$lck_cnt"
12254
12255         rm $DIR/$tdir/m
12256         unlinkmany $DIR/$tdir/f $nr
12257 }
12258 run_test 134a "Server reclaims locks when reaching lock_reclaim_threshold"
12259
12260 test_134b() {
12261         remote_mds_nodsh && skip "remote MDS with nodsh"
12262         [[ $MDS1_VERSION -lt $(version_code 2.7.54) ]] &&
12263                 skip "Need MDS version at least 2.7.54"
12264
12265         mkdir -p $DIR/$tdir || error "failed to create $DIR/$tdir"
12266         cancel_lru_locks mdc
12267
12268         local low_wm=$(do_facet mds1 $LCTL get_param -n \
12269                         ldlm.lock_reclaim_threshold_mb)
12270         # disable reclaim temporarily
12271         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=0
12272
12273         #define OBD_FAIL_LDLM_WATERMARK_HIGH     0x328
12274         do_facet mds1 $LCTL set_param fail_loc=0x328
12275         do_facet mds1 $LCTL set_param fail_val=500
12276
12277         $LCTL set_param debug=+trace
12278
12279         local nr=600
12280         createmany -o $DIR/$tdir/f $nr &
12281         local create_pid=$!
12282
12283         echo "Sleep $TIMEOUT seconds ..."
12284         sleep $TIMEOUT
12285         if ! ps -p $create_pid  > /dev/null 2>&1; then
12286                 do_facet mds1 $LCTL set_param fail_loc=0
12287                 do_facet mds1 $LCTL set_param fail_val=0
12288                 do_facet mds1 $LCTL set_param \
12289                         ldlm.lock_reclaim_threshold_mb=${low_wm}m
12290                 error "createmany finished incorrectly!"
12291         fi
12292         do_facet mds1 $LCTL set_param fail_loc=0
12293         do_facet mds1 $LCTL set_param fail_val=0
12294         do_facet mds1 $LCTL set_param ldlm.lock_reclaim_threshold_mb=${low_wm}m
12295         wait $create_pid || return 1
12296
12297         unlinkmany $DIR/$tdir/f $nr
12298 }
12299 run_test 134b "Server rejects lock request when reaching lock_limit_mb"
12300
12301 test_140() { #bug-17379
12302         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12303
12304         test_mkdir $DIR/$tdir
12305         cd $DIR/$tdir || error "Changing to $DIR/$tdir"
12306         cp $(which stat) . || error "Copying stat to $DIR/$tdir"
12307
12308         # VFS limits max symlink depth to 5(4KSTACK) or 7(8KSTACK) or 8
12309         # For kernel > 3.5, bellow only tests consecutive symlink (MAX 40)
12310         local i=0
12311         while i=$((i + 1)); do
12312                 test_mkdir $i
12313                 cd $i || error "Changing to $i"
12314                 ln -s ../stat stat || error "Creating stat symlink"
12315                 # Read the symlink until ELOOP present,
12316                 # not LBUGing the system is considered success,
12317                 # we didn't overrun the stack.
12318                 $OPENFILE -f O_RDONLY stat >/dev/null 2>&1; ret=$?
12319                 if [ $ret -ne 0 ]; then
12320                         if [ $ret -eq 40 ]; then
12321                                 break  # -ELOOP
12322                         else
12323                                 error "Open stat symlink"
12324                                         return
12325                         fi
12326                 fi
12327         done
12328         i=$((i - 1))
12329         echo "The symlink depth = $i"
12330         [ $i -eq 5 ] || [ $i -eq 7 ] || [ $i -eq 8 ] || [ $i -eq 40 ] ||
12331                 error "Invalid symlink depth"
12332
12333         # Test recursive symlink
12334         ln -s symlink_self symlink_self
12335         $OPENFILE -f O_RDONLY symlink_self >/dev/null 2>&1; ret=$?
12336         echo "open symlink_self returns $ret"
12337         [ $ret -eq 40 ] || error "recursive symlink doesn't return -ELOOP"
12338 }
12339 run_test 140 "Check reasonable stack depth (shouldn't LBUG) ===="
12340
12341 test_150() {
12342         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12343
12344         local TF="$TMP/$tfile"
12345
12346         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12347         cp $TF $DIR/$tfile
12348         cancel_lru_locks $OSC
12349         cmp $TF $DIR/$tfile || error "$TMP/$tfile $DIR/$tfile differ"
12350         remount_client $MOUNT
12351         df -P $MOUNT
12352         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (remount)"
12353
12354         $TRUNCATE $TF 6000
12355         $TRUNCATE $DIR/$tfile 6000
12356         cancel_lru_locks $OSC
12357         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (truncate1)"
12358
12359         echo "12345" >>$TF
12360         echo "12345" >>$DIR/$tfile
12361         cancel_lru_locks $OSC
12362         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append1)"
12363
12364         echo "12345" >>$TF
12365         echo "12345" >>$DIR/$tfile
12366         cancel_lru_locks $OSC
12367         cmp $TF $DIR/$tfile || error "$TF $DIR/$tfile differ (append2)"
12368
12369         rm -f $TF
12370         true
12371 }
12372 run_test 150 "truncate/append tests"
12373
12374 #LU-2902 roc_hit was not able to read all values from lproc
12375 function roc_hit_init() {
12376         local list=$(comma_list $(osts_nodes))
12377         local dir=$DIR/$tdir-check
12378         local file=$dir/$tfile
12379         local BEFORE
12380         local AFTER
12381         local idx
12382
12383         test_mkdir $dir
12384         #use setstripe to do a write to every ost
12385         for i in $(seq 0 $((OSTCOUNT-1))); do
12386                 $LFS setstripe -c 1 -i $i $dir || error "$LFS setstripe $file failed"
12387                 dd if=/dev/urandom of=$file bs=4k count=4 2>&1 > /dev/null
12388                 idx=$(printf %04x $i)
12389                 BEFORE=$(get_osd_param $list *OST*$idx stats |
12390                         awk '$1 == "cache_access" {sum += $7}
12391                                 END { printf("%0.0f", sum) }')
12392
12393                 cancel_lru_locks osc
12394                 cat $file >/dev/null
12395
12396                 AFTER=$(get_osd_param $list *OST*$idx stats |
12397                         awk '$1 == "cache_access" {sum += $7}
12398                                 END { printf("%0.0f", sum) }')
12399
12400                 echo BEFORE:$BEFORE AFTER:$AFTER
12401                 if ! let "AFTER - BEFORE == 4"; then
12402                         rm -rf $dir
12403                         error "roc_hit is not safe to use"
12404                 fi
12405                 rm $file
12406         done
12407
12408         rm -rf $dir
12409 }
12410
12411 function roc_hit() {
12412         local list=$(comma_list $(osts_nodes))
12413         echo $(get_osd_param $list '' stats |
12414                 awk '$1 == "cache_hit" {sum += $7}
12415                         END { printf("%0.0f", sum) }')
12416 }
12417
12418 function set_cache() {
12419         local on=1
12420
12421         if [ "$2" == "off" ]; then
12422                 on=0;
12423         fi
12424         local list=$(comma_list $(osts_nodes))
12425         set_osd_param $list '' $1_cache_enable $on
12426
12427         cancel_lru_locks osc
12428 }
12429
12430 test_151() {
12431         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12432         remote_ost_nodsh && skip "remote OST with nodsh"
12433
12434         local CPAGES=3
12435         local list=$(comma_list $(osts_nodes))
12436
12437         # check whether obdfilter is cache capable at all
12438         if ! get_osd_param $list '' read_cache_enable >/dev/null; then
12439                 skip "not cache-capable obdfilter"
12440         fi
12441
12442         # check cache is enabled on all obdfilters
12443         if get_osd_param $list '' read_cache_enable | grep 0; then
12444                 skip "oss cache is disabled"
12445         fi
12446
12447         set_osd_param $list '' writethrough_cache_enable 1
12448
12449         # check write cache is enabled on all obdfilters
12450         if get_osd_param $list '' writethrough_cache_enable | grep 0; then
12451                 skip "oss write cache is NOT enabled"
12452         fi
12453
12454         roc_hit_init
12455
12456         #define OBD_FAIL_OBD_NO_LRU  0x609
12457         do_nodes $list $LCTL set_param fail_loc=0x609
12458
12459         # pages should be in the case right after write
12460         dd if=/dev/urandom of=$DIR/$tfile bs=4k count=$CPAGES ||
12461                 error "dd failed"
12462
12463         local BEFORE=$(roc_hit)
12464         cancel_lru_locks osc
12465         cat $DIR/$tfile >/dev/null
12466         local AFTER=$(roc_hit)
12467
12468         do_nodes $list $LCTL set_param fail_loc=0
12469
12470         if ! let "AFTER - BEFORE == CPAGES"; then
12471                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
12472         fi
12473
12474         # the following read invalidates the cache
12475         cancel_lru_locks osc
12476         set_osd_param $list '' read_cache_enable 0
12477         cat $DIR/$tfile >/dev/null
12478
12479         # now data shouldn't be found in the cache
12480         BEFORE=$(roc_hit)
12481         cancel_lru_locks osc
12482         cat $DIR/$tfile >/dev/null
12483         AFTER=$(roc_hit)
12484         if let "AFTER - BEFORE != 0"; then
12485                 error "IN CACHE: before: $BEFORE, after: $AFTER"
12486         fi
12487
12488         set_osd_param $list '' read_cache_enable 1
12489         rm -f $DIR/$tfile
12490 }
12491 run_test 151 "test cache on oss and controls ==============================="
12492
12493 test_152() {
12494         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12495
12496         local TF="$TMP/$tfile"
12497
12498         # simulate ENOMEM during write
12499 #define OBD_FAIL_OST_NOMEM      0x226
12500         lctl set_param fail_loc=0x80000226
12501         dd if=/dev/urandom of=$TF bs=6096 count=1 || error "dd failed"
12502         cp $TF $DIR/$tfile
12503         sync || error "sync failed"
12504         lctl set_param fail_loc=0
12505
12506         # discard client's cache
12507         cancel_lru_locks osc
12508
12509         # simulate ENOMEM during read
12510         lctl set_param fail_loc=0x80000226
12511         cmp $TF $DIR/$tfile || error "cmp failed"
12512         lctl set_param fail_loc=0
12513
12514         rm -f $TF
12515 }
12516 run_test 152 "test read/write with enomem ============================"
12517
12518 test_153() {
12519         $MULTIOP $DIR/$tfile Ow4096Ycu || error "multiop failed"
12520 }
12521 run_test 153 "test if fdatasync does not crash ======================="
12522
12523 dot_lustre_fid_permission_check() {
12524         local fid=$1
12525         local ffid=$MOUNT/.lustre/fid/$fid
12526         local test_dir=$2
12527
12528         echo "stat fid $fid"
12529         stat $ffid > /dev/null || error "stat $ffid failed."
12530         echo "touch fid $fid"
12531         touch $ffid || error "touch $ffid failed."
12532         echo "write to fid $fid"
12533         cat /etc/hosts > $ffid || error "write $ffid failed."
12534         echo "read fid $fid"
12535         diff /etc/hosts $ffid || error "read $ffid failed."
12536         echo "append write to fid $fid"
12537         cat /etc/hosts >> $ffid || error "append write $ffid failed."
12538         echo "rename fid $fid"
12539         mv $ffid $test_dir/$tfile.1 &&
12540                 error "rename $ffid to $tfile.1 should fail."
12541         touch $test_dir/$tfile.1
12542         mv $test_dir/$tfile.1 $ffid &&
12543                 error "rename $tfile.1 to $ffid should fail."
12544         rm -f $test_dir/$tfile.1
12545         echo "truncate fid $fid"
12546         $TRUNCATE $ffid 777 || error "truncate $ffid failed."
12547         echo "link fid $fid"
12548         ln -f $ffid $test_dir/tfile.lnk || error "link $ffid failed."
12549         if [[ $($LCTL get_param -n mdc.*-mdc-*.connect_flags) =~ acl ]]; then
12550                 echo "setfacl fid $fid"
12551                 setfacl -R -m u:bin:rwx $ffid || error "setfacl $ffid failed."
12552                 echo "getfacl fid $fid"
12553                 getfacl $ffid >/dev/null || error "getfacl $ffid failed."
12554         fi
12555         echo "unlink fid $fid"
12556         unlink $MOUNT/.lustre/fid/$fid && error "unlink $ffid should fail."
12557         echo "mknod fid $fid"
12558         mknod $ffid c 1 3 && error "mknod $ffid should fail."
12559
12560         fid=[0xf00000400:0x1:0x0]
12561         ffid=$MOUNT/.lustre/fid/$fid
12562
12563         echo "stat non-exist fid $fid"
12564         stat $ffid > /dev/null && error "stat non-exist $ffid should fail."
12565         echo "write to non-exist fid $fid"
12566         cat /etc/hosts > $ffid && error "write non-exist $ffid should fail."
12567         echo "link new fid $fid"
12568         ln $test_dir/$tfile $ffid && error "link $ffid should fail."
12569
12570         mkdir -p $test_dir/$tdir
12571         touch $test_dir/$tdir/$tfile
12572         fid=$($LFS path2fid $test_dir/$tdir)
12573         rc=$?
12574         [ $rc -ne 0 ] &&
12575                 error "error: could not get fid for $test_dir/$dir/$tfile."
12576
12577         ffid=$MOUNT/.lustre/fid/$fid
12578
12579         echo "ls $fid"
12580         ls $ffid > /dev/null || error "ls $ffid failed."
12581         echo "touch $fid/$tfile.1"
12582         touch $ffid/$tfile.1 || error "touch $ffid/$tfile.1 failed."
12583
12584         echo "touch $MOUNT/.lustre/fid/$tfile"
12585         touch $MOUNT/.lustre/fid/$tfile && \
12586                 error "touch $MOUNT/.lustre/fid/$tfile should fail."
12587
12588         echo "setxattr to $MOUNT/.lustre/fid"
12589         setfattr -n trusted.name1 -v value1 $MOUNT/.lustre/fid
12590
12591         echo "listxattr for $MOUNT/.lustre/fid"
12592         getfattr -d -m "^trusted" $MOUNT/.lustre/fid
12593
12594         echo "delxattr from $MOUNT/.lustre/fid"
12595         setfattr -x trusted.name1 $MOUNT/.lustre/fid
12596
12597         echo "touch invalid fid: $MOUNT/.lustre/fid/[0x200000400:0x2:0x3]"
12598         touch $MOUNT/.lustre/fid/[0x200000400:0x2:0x3] &&
12599                 error "touch invalid fid should fail."
12600
12601         echo "touch non-normal fid: $MOUNT/.lustre/fid/[0x1:0x2:0x0]"
12602         touch $MOUNT/.lustre/fid/[0x1:0x2:0x0] &&
12603                 error "touch non-normal fid should fail."
12604
12605         echo "rename $tdir to $MOUNT/.lustre/fid"
12606         mrename $test_dir/$tdir $MOUNT/.lustre/fid &&
12607                 error "rename to $MOUNT/.lustre/fid should fail."
12608
12609         if [ $MDS1_VERSION -ge $(version_code 2.3.51) ]
12610         then            # LU-3547
12611                 local old_obf_mode=$(stat --format="%a" $DIR/.lustre/fid)
12612                 local new_obf_mode=777
12613
12614                 echo "change mode of $DIR/.lustre/fid to $new_obf_mode"
12615                 chmod $new_obf_mode $DIR/.lustre/fid ||
12616                         error "chmod $new_obf_mode $DIR/.lustre/fid failed"
12617
12618                 local obf_mode=$(stat --format=%a $DIR/.lustre/fid)
12619                 [ $obf_mode -eq $new_obf_mode ] ||
12620                         error "stat $DIR/.lustre/fid returned wrong mode $obf_mode"
12621
12622                 echo "restore mode of $DIR/.lustre/fid to $old_obf_mode"
12623                 chmod $old_obf_mode $DIR/.lustre/fid ||
12624                         error "chmod $old_obf_mode $DIR/.lustre/fid failed"
12625         fi
12626
12627         $OPENFILE -f O_LOV_DELAY_CREATE:O_CREAT $test_dir/$tfile-2
12628         fid=$($LFS path2fid $test_dir/$tfile-2)
12629
12630         if [ $MDS1_VERSION -ge $(version_code 2.6.50) ]
12631         then # LU-5424
12632                 echo "cp /etc/passwd $MOUNT/.lustre/fid/$fid"
12633                 cp /etc/passwd $MOUNT/.lustre/fid/$fid ||
12634                         error "create lov data thru .lustre failed"
12635         fi
12636         echo "cp /etc/passwd $test_dir/$tfile-2"
12637         cp /etc/passwd $test_dir/$tfile-2 ||
12638                 error "copy to $test_dir/$tfile-2 failed."
12639         echo "diff /etc/passwd $MOUNT/.lustre/fid/$fid"
12640         diff /etc/passwd $MOUNT/.lustre/fid/$fid ||
12641                 error "diff /etc/passwd $MOUNT/.lustre/fid/$fid failed."
12642
12643         rm -rf $test_dir/tfile.lnk
12644         rm -rf $test_dir/$tfile-2
12645 }
12646
12647 test_154A() {
12648         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12649                 skip "Need MDS version at least 2.4.1"
12650
12651         local tf=$DIR/$tfile
12652         touch $tf
12653
12654         local fid=$($LFS path2fid $tf)
12655         [ -z "$fid" ] && error "path2fid unable to get $tf FID"
12656
12657         # check that we get the same pathname back
12658         local found=$($LFS fid2path $MOUNT "$fid")
12659         [ -z "$found" ] && error "fid2path unable to get '$fid' path"
12660         [ "$found" == "$tf" ] ||
12661                 error "fid2path($fid=path2fid($tf)) = $found != $tf"
12662 }
12663 run_test 154A "lfs path2fid and fid2path basic checks"
12664
12665 test_154B() {
12666         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12667                 skip "Need MDS version at least 2.4.1"
12668
12669         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
12670         touch $DIR/$tdir/$tfile || error "touch $DIR/$tdir/$tfile failed"
12671         local linkea=$($LL_DECODE_LINKEA $DIR/$tdir/$tfile | grep 'pfid')
12672         [ -z "$linkea" ] && error "decode linkea $DIR/$tdir/$tfile failed"
12673
12674         local name=$(echo $linkea | awk '/pfid/ {print $5}' | sed -e "s/'//g")
12675         local PFID=$(echo $linkea | awk '/pfid/ {print $3}' | sed -e "s/,//g")
12676
12677         # check that we get the same pathname
12678         echo "PFID: $PFID, name: $name"
12679         local FOUND=$($LFS fid2path $MOUNT "$PFID")
12680         [ -z "$FOUND" ] && error "fid2path unable to get $PFID path"
12681         [ "$FOUND/$name" != "$DIR/$tdir/$tfile" ] &&
12682                 error "ll_decode_linkea has $FOUND/$name != $DIR/$tdir/$tfile"
12683
12684         rm -rf $DIR/$tdir || error "Can not delete directory $DIR/$tdir"
12685 }
12686 run_test 154B "verify the ll_decode_linkea tool"
12687
12688 test_154a() {
12689         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12690         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12691         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12692                 skip "Need MDS version at least 2.2.51"
12693         [ -z "$(which setfacl)" ] && skip_env "must have setfacl tool"
12694
12695         cp /etc/hosts $DIR/$tfile
12696
12697         fid=$($LFS path2fid $DIR/$tfile)
12698         rc=$?
12699         [ $rc -ne 0 ] && error "error: could not get fid for $DIR/$tfile."
12700
12701         dot_lustre_fid_permission_check "$fid" $DIR ||
12702                 error "dot lustre permission check $fid failed"
12703
12704         ls -a $MOUNT | grep "\.lustre" && error ".lustre should not be listed"
12705
12706         rm -rf $MOUNT/.lustre && error ".lustre is not allowed to be unlinked"
12707
12708         touch $MOUNT/.lustre/file &&
12709                 error "creation is not allowed under .lustre"
12710
12711         mkdir $MOUNT/.lustre/dir &&
12712                 error "mkdir is not allowed under .lustre"
12713
12714         rm -rf $DIR/$tfile
12715 }
12716 run_test 154a "Open-by-FID"
12717
12718 test_154b() {
12719         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12720         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12721         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
12722         [[ $MDS1_VERSION -ge $(version_code 2.2.51) ]] ||
12723                 skip "Need MDS version at least 2.2.51"
12724
12725         local remote_dir=$DIR/$tdir/remote_dir
12726         local MDTIDX=1
12727         local rc=0
12728
12729         mkdir -p $DIR/$tdir
12730         $LFS mkdir -i $MDTIDX $remote_dir ||
12731                 error "create remote directory failed"
12732
12733         cp /etc/hosts $remote_dir/$tfile
12734
12735         fid=$($LFS path2fid $remote_dir/$tfile)
12736         rc=$?
12737         [ $rc -ne 0 ] && error "error: could not get fid for $remote_dir/$tfile"
12738
12739         dot_lustre_fid_permission_check "$fid" $remote_dir ||
12740                 error "dot lustre permission check $fid failed"
12741         rm -rf $DIR/$tdir
12742 }
12743 run_test 154b "Open-by-FID for remote directory"
12744
12745 test_154c() {
12746         [[ $MDS1_VERSION -lt $(version_code 2.4.1) ]] &&
12747                 skip "Need MDS version at least 2.4.1"
12748
12749         touch $DIR/$tfile.1 $DIR/$tfile.2 $DIR/$tfile.3
12750         local FID1=$($LFS path2fid $DIR/$tfile.1)
12751         local FID2=$($LFS path2fid $DIR/$tfile.2)
12752         local FID3=$($LFS path2fid $DIR/$tfile.3)
12753
12754         local N=1
12755         $LFS path2fid $DIR/$tfile.[123] | while read PATHNAME FID; do
12756                 [ "$PATHNAME" = "$DIR/$tfile.$N:" ] ||
12757                         error "path2fid pathname $PATHNAME != $DIR/$tfile.$N:"
12758                 local want=FID$N
12759                 [ "$FID" = "${!want}" ] ||
12760                         error "path2fid $PATHNAME FID $FID != FID$N ${!want}"
12761                 N=$((N + 1))
12762         done
12763
12764         $LFS fid2path $MOUNT "$FID1" "$FID2" "$FID3" | while read PATHNAME;
12765         do
12766                 [ "$PATHNAME" = "$DIR/$tfile.$N" ] ||
12767                         error "fid2path pathname $PATHNAME != $DIR/$tfile.$N:"
12768                 N=$((N + 1))
12769         done
12770 }
12771 run_test 154c "lfs path2fid and fid2path multiple arguments"
12772
12773 test_154d() {
12774         remote_mds_nodsh && skip "remote MDS with nodsh"
12775         [[ $MDS1_VERSION -lt $(version_code 2.5.53) ]] &&
12776                 skip "Need MDS version at least 2.5.53"
12777
12778         if remote_mds; then
12779                 nid=$($LCTL list_nids | sed  "s/\./\\\./g")
12780         else
12781                 nid="0@lo"
12782         fi
12783         local proc_ofile="mdt.*.exports.'$nid'.open_files"
12784         local fd
12785         local cmd
12786
12787         rm -f $DIR/$tfile
12788         touch $DIR/$tfile
12789
12790         local fid=$($LFS path2fid $DIR/$tfile)
12791         # Open the file
12792         fd=$(free_fd)
12793         cmd="exec $fd<$DIR/$tfile"
12794         eval $cmd
12795         local fid_list=$(do_facet $SINGLEMDS $LCTL get_param $proc_ofile)
12796         echo "$fid_list" | grep "$fid"
12797         rc=$?
12798
12799         cmd="exec $fd>/dev/null"
12800         eval $cmd
12801         if [ $rc -ne 0 ]; then
12802                 error "FID $fid not found in open files list $fid_list"
12803         fi
12804 }
12805 run_test 154d "Verify open file fid"
12806
12807 test_154e()
12808 {
12809         [[ $MDS1_VERSION -lt $(version_code 2.6.50) ]] &&
12810                 skip "Need MDS version at least 2.6.50"
12811
12812         if ls -a $MOUNT | grep -q '^\.lustre$'; then
12813                 error ".lustre returned by readdir"
12814         fi
12815 }
12816 run_test 154e ".lustre is not returned by readdir"
12817
12818 test_154f() {
12819         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12820
12821         # create parent directory on a single MDT to avoid cross-MDT hardlinks
12822         test_mkdir -p -c1 $DIR/$tdir/d
12823         # test dirs inherit from its stripe
12824         mkdir -p $DIR/$tdir/d/foo1 || error "mkdir error"
12825         mkdir -p $DIR/$tdir/d/foo2 || error "mkdir error"
12826         cp /etc/hosts $DIR/$tdir/d/foo1/$tfile
12827         ln $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/link
12828         touch $DIR/f
12829
12830         # get fid of parents
12831         local FID0=$($LFS path2fid $DIR/$tdir/d)
12832         local FID1=$($LFS path2fid $DIR/$tdir/d/foo1)
12833         local FID2=$($LFS path2fid $DIR/$tdir/d/foo2)
12834         local FID3=$($LFS path2fid $DIR)
12835
12836         # check that path2fid --parents returns expected <parent_fid>/name
12837         # 1) test for a directory (single parent)
12838         local parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1)
12839         [ "$parent" == "$FID0/foo1" ] ||
12840                 error "expected parent: $FID0/foo1, got: $parent"
12841
12842         # 2) test for a file with nlink > 1 (multiple parents)
12843         parent=$($LFS path2fid --parents $DIR/$tdir/d/foo1/$tfile)
12844         echo "$parent" | grep -F "$FID1/$tfile" ||
12845                 error "$FID1/$tfile not returned in parent list"
12846         echo "$parent" | grep -F "$FID2/link" ||
12847                 error "$FID2/link not returned in parent list"
12848
12849         # 3) get parent by fid
12850         local file_fid=$($LFS path2fid $DIR/$tdir/d/foo1/$tfile)
12851         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12852         echo "$parent" | grep -F "$FID1/$tfile" ||
12853                 error "$FID1/$tfile not returned in parent list (by fid)"
12854         echo "$parent" | grep -F "$FID2/link" ||
12855                 error "$FID2/link not returned in parent list (by fid)"
12856
12857         # 4) test for entry in root directory
12858         parent=$($LFS path2fid --parents $DIR/f)
12859         echo "$parent" | grep -F "$FID3/f" ||
12860                 error "$FID3/f not returned in parent list"
12861
12862         # 5) test it on root directory
12863         [ -z "$($LFS path2fid --parents $MOUNT 2>/dev/null)" ] ||
12864                 error "$MOUNT should not have parents"
12865
12866         # enable xattr caching and check that linkea is correctly updated
12867         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
12868         save_lustre_params client "llite.*.xattr_cache" > $save
12869         lctl set_param llite.*.xattr_cache 1
12870
12871         # 6.1) linkea update on rename
12872         mv $DIR/$tdir/d/foo1/$tfile $DIR/$tdir/d/foo2/$tfile.moved
12873
12874         # get parents by fid
12875         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12876         # foo1 should no longer be returned in parent list
12877         echo "$parent" | grep -F "$FID1" &&
12878                 error "$FID1 should no longer be in parent list"
12879         # the new path should appear
12880         echo "$parent" | grep -F "$FID2/$tfile.moved" ||
12881                 error "$FID2/$tfile.moved is not in parent list"
12882
12883         # 6.2) linkea update on unlink
12884         rm -f $DIR/$tdir/d/foo2/link
12885         parent=$($LFS path2fid --parents $MOUNT/.lustre/fid/$file_fid)
12886         # foo2/link should no longer be returned in parent list
12887         echo "$parent" | grep -F "$FID2/link" &&
12888                 error "$FID2/link should no longer be in parent list"
12889         true
12890
12891         rm -f $DIR/f
12892         restore_lustre_params < $save
12893         rm -f $save
12894 }
12895 run_test 154f "get parent fids by reading link ea"
12896
12897 test_154g()
12898 {
12899         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
12900         [[ $MDS1_VERSION -ge $(version_code 2.6.92) &&
12901            $CLIENT_VERSION -gt $(version_code 2.6.99) ]] ||
12902                 skip "Need MDS version at least 2.6.92"
12903
12904         mkdir -p $DIR/$tdir
12905         llapi_fid_test -d $DIR/$tdir
12906 }
12907 run_test 154g "various llapi FID tests"
12908
12909 test_155_small_load() {
12910     local temp=$TMP/$tfile
12911     local file=$DIR/$tfile
12912
12913     dd if=/dev/urandom of=$temp bs=6096 count=1 || \
12914         error "dd of=$temp bs=6096 count=1 failed"
12915     cp $temp $file
12916     cancel_lru_locks $OSC
12917     cmp $temp $file || error "$temp $file differ"
12918
12919     $TRUNCATE $temp 6000
12920     $TRUNCATE $file 6000
12921     cmp $temp $file || error "$temp $file differ (truncate1)"
12922
12923     echo "12345" >>$temp
12924     echo "12345" >>$file
12925     cmp $temp $file || error "$temp $file differ (append1)"
12926
12927     echo "12345" >>$temp
12928     echo "12345" >>$file
12929     cmp $temp $file || error "$temp $file differ (append2)"
12930
12931     rm -f $temp $file
12932     true
12933 }
12934
12935 test_155_big_load() {
12936         remote_ost_nodsh && skip "remote OST with nodsh"
12937
12938         local temp=$TMP/$tfile
12939         local file=$DIR/$tfile
12940
12941         free_min_max
12942         local cache_size=$(do_facet ost$((MAXI+1)) \
12943                 "awk '/cache/ {sum+=\\\$4} END {print sum}' /proc/cpuinfo")
12944         local large_file_size=$((cache_size * 2))
12945
12946         echo "OSS cache size: $cache_size KB"
12947         echo "Large file size: $large_file_size KB"
12948
12949         [ $MAXV -le $large_file_size ] &&
12950                 skip_env "max available OST size needs > $large_file_size KB"
12951
12952         $LFS setstripe $file -c 1 -i $MAXI || error "$LFS setstripe $file failed"
12953
12954         dd if=/dev/urandom of=$temp bs=$large_file_size count=1k ||
12955                 error "dd of=$temp bs=$large_file_size count=1k failed"
12956         cp $temp $file
12957         ls -lh $temp $file
12958         cancel_lru_locks osc
12959         cmp $temp $file || error "$temp $file differ"
12960
12961         rm -f $temp $file
12962         true
12963 }
12964
12965 save_writethrough() {
12966         local facets=$(get_facets OST)
12967
12968         save_lustre_params $facets "osd-*.*.writethrough_cache_enable" > $1
12969 }
12970
12971 test_155a() {
12972         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12973
12974         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12975
12976         save_writethrough $p
12977
12978         set_cache read on
12979         set_cache writethrough on
12980         test_155_small_load
12981         restore_lustre_params < $p
12982         rm -f $p
12983 }
12984 run_test 155a "Verify small file correctness: read cache:on write_cache:on"
12985
12986 test_155b() {
12987         [ $PARALLEL == "yes" ] && skip "skip parallel run"
12988
12989         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
12990
12991         save_writethrough $p
12992
12993         set_cache read on
12994         set_cache writethrough off
12995         test_155_small_load
12996         restore_lustre_params < $p
12997         rm -f $p
12998 }
12999 run_test 155b "Verify small file correctness: read cache:on write_cache:off"
13000
13001 test_155c() {
13002         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13003
13004         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13005
13006         save_writethrough $p
13007
13008         set_cache read off
13009         set_cache writethrough on
13010         test_155_small_load
13011         restore_lustre_params < $p
13012         rm -f $p
13013 }
13014 run_test 155c "Verify small file correctness: read cache:off write_cache:on"
13015
13016 test_155d() {
13017         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13018
13019         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13020
13021         save_writethrough $p
13022
13023         set_cache read off
13024         set_cache writethrough off
13025         test_155_small_load
13026         restore_lustre_params < $p
13027         rm -f $p
13028 }
13029 run_test 155d "Verify small file correctness: read cache:off write_cache:off"
13030
13031 test_155e() {
13032         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13033
13034         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13035
13036         save_writethrough $p
13037
13038         set_cache read on
13039         set_cache writethrough on
13040         test_155_big_load
13041         restore_lustre_params < $p
13042         rm -f $p
13043 }
13044 run_test 155e "Verify big file correctness: read cache:on write_cache:on"
13045
13046 test_155f() {
13047         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13048
13049         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13050
13051         save_writethrough $p
13052
13053         set_cache read on
13054         set_cache writethrough off
13055         test_155_big_load
13056         restore_lustre_params < $p
13057         rm -f $p
13058 }
13059 run_test 155f "Verify big file correctness: read cache:on write_cache:off"
13060
13061 test_155g() {
13062         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13063
13064         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13065
13066         save_writethrough $p
13067
13068         set_cache read off
13069         set_cache writethrough on
13070         test_155_big_load
13071         restore_lustre_params < $p
13072         rm -f $p
13073 }
13074 run_test 155g "Verify big file correctness: read cache:off write_cache:on"
13075
13076 test_155h() {
13077         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13078
13079         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13080
13081         save_writethrough $p
13082
13083         set_cache read off
13084         set_cache writethrough off
13085         test_155_big_load
13086         restore_lustre_params < $p
13087         rm -f $p
13088 }
13089 run_test 155h "Verify big file correctness: read cache:off write_cache:off"
13090
13091 test_156() {
13092         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13093         remote_ost_nodsh && skip "remote OST with nodsh"
13094         [ $OST1_VERSION -lt $(version_code 2.6.93) ] &&
13095                 skip "stats not implemented on old servers"
13096         [ "$ost1_FSTYPE" = "zfs" ] &&
13097                 skip "LU-1956/LU-2261: stats not implemented on OSD ZFS"
13098
13099         local CPAGES=3
13100         local BEFORE
13101         local AFTER
13102         local file="$DIR/$tfile"
13103         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
13104
13105         save_writethrough $p
13106         roc_hit_init
13107
13108         log "Turn on read and write cache"
13109         set_cache read on
13110         set_cache writethrough on
13111
13112         log "Write data and read it back."
13113         log "Read should be satisfied from the cache."
13114         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13115         BEFORE=$(roc_hit)
13116         cancel_lru_locks osc
13117         cat $file >/dev/null
13118         AFTER=$(roc_hit)
13119         if ! let "AFTER - BEFORE == CPAGES"; then
13120                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13121         else
13122                 log "cache hits:: before: $BEFORE, after: $AFTER"
13123         fi
13124
13125         log "Read again; it should be satisfied from the cache."
13126         BEFORE=$AFTER
13127         cancel_lru_locks osc
13128         cat $file >/dev/null
13129         AFTER=$(roc_hit)
13130         if ! let "AFTER - BEFORE == CPAGES"; then
13131                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13132         else
13133                 log "cache hits:: before: $BEFORE, after: $AFTER"
13134         fi
13135
13136         log "Turn off the read cache and turn on the write cache"
13137         set_cache read off
13138         set_cache writethrough on
13139
13140         log "Read again; it should be satisfied from the cache."
13141         BEFORE=$(roc_hit)
13142         cancel_lru_locks osc
13143         cat $file >/dev/null
13144         AFTER=$(roc_hit)
13145         if ! let "AFTER - BEFORE == CPAGES"; then
13146                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13147         else
13148                 log "cache hits:: before: $BEFORE, after: $AFTER"
13149         fi
13150
13151         log "Read again; it should not be satisfied from the cache."
13152         BEFORE=$AFTER
13153         cancel_lru_locks osc
13154         cat $file >/dev/null
13155         AFTER=$(roc_hit)
13156         if ! let "AFTER - BEFORE == 0"; then
13157                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13158         else
13159                 log "cache hits:: before: $BEFORE, after: $AFTER"
13160         fi
13161
13162         log "Write data and read it back."
13163         log "Read should be satisfied from the cache."
13164         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13165         BEFORE=$(roc_hit)
13166         cancel_lru_locks osc
13167         cat $file >/dev/null
13168         AFTER=$(roc_hit)
13169         if ! let "AFTER - BEFORE == CPAGES"; then
13170                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13171         else
13172                 log "cache hits:: before: $BEFORE, after: $AFTER"
13173         fi
13174
13175         log "Read again; it should not be satisfied from the cache."
13176         BEFORE=$AFTER
13177         cancel_lru_locks osc
13178         cat $file >/dev/null
13179         AFTER=$(roc_hit)
13180         if ! let "AFTER - BEFORE == 0"; then
13181                 error "IN CACHE: before: $BEFORE, after: $AFTER"
13182         else
13183                 log "cache hits:: before: $BEFORE, after: $AFTER"
13184         fi
13185
13186         log "Turn off read and write cache"
13187         set_cache read off
13188         set_cache writethrough off
13189
13190         log "Write data and read it back"
13191         log "It should not be satisfied from the cache."
13192         rm -f $file
13193         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13194         cancel_lru_locks osc
13195         BEFORE=$(roc_hit)
13196         cat $file >/dev/null
13197         AFTER=$(roc_hit)
13198         if ! let "AFTER - BEFORE == 0"; then
13199                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13200         else
13201                 log "cache hits:: before: $BEFORE, after: $AFTER"
13202         fi
13203
13204         log "Turn on the read cache and turn off the write cache"
13205         set_cache read on
13206         set_cache writethrough off
13207
13208         log "Write data and read it back"
13209         log "It should not be satisfied from the cache."
13210         rm -f $file
13211         dd if=/dev/urandom of=$file bs=4k count=$CPAGES || error "dd failed"
13212         BEFORE=$(roc_hit)
13213         cancel_lru_locks osc
13214         cat $file >/dev/null
13215         AFTER=$(roc_hit)
13216         if ! let "AFTER - BEFORE == 0"; then
13217                 error_ignore bz20762 "IN CACHE: before: $BEFORE, after: $AFTER"
13218         else
13219                 log "cache hits:: before: $BEFORE, after: $AFTER"
13220         fi
13221
13222         log "Read again; it should be satisfied from the cache."
13223         BEFORE=$(roc_hit)
13224         cancel_lru_locks osc
13225         cat $file >/dev/null
13226         AFTER=$(roc_hit)
13227         if ! let "AFTER - BEFORE == CPAGES"; then
13228                 error "NOT IN CACHE: before: $BEFORE, after: $AFTER"
13229         else
13230                 log "cache hits:: before: $BEFORE, after: $AFTER"
13231         fi
13232
13233         restore_lustre_params < $p
13234         rm -f $p $file
13235 }
13236 run_test 156 "Verification of tunables"
13237
13238 test_160a() {
13239         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13240         remote_mds_nodsh && skip "remote MDS with nodsh"
13241         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13242                 skip "Need MDS version at least 2.2.0"
13243
13244         changelog_register || error "changelog_register failed"
13245         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13246         changelog_users $SINGLEMDS | grep -q $cl_user ||
13247                 error "User $cl_user not found in changelog_users"
13248
13249         # change something
13250         test_mkdir -p $DIR/$tdir/pics/2008/zachy
13251         changelog_clear 0 || error "changelog_clear failed"
13252         touch $DIR/$tdir/pics/2008/zachy/$tfile                 # open 1
13253         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg       # open 2
13254         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
13255         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
13256         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
13257         rm $DIR/$tdir/pics/desktop.jpg
13258
13259         changelog_dump | tail -10
13260
13261         echo "verifying changelog mask"
13262         changelog_chmask "-MKDIR"
13263         changelog_chmask "-CLOSE"
13264
13265         test_mkdir -p $DIR/$tdir/pics/zach/sofia                # not logged
13266         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # not logged
13267
13268         changelog_chmask "+MKDIR"
13269         changelog_chmask "+CLOSE"
13270
13271         test_mkdir -p $DIR/$tdir/pics/2008/sofia                # mkdir 1
13272         echo "zzzzzz" > $DIR/$tdir/pics/zach/file               # open 3
13273
13274         changelog_dump | tail -10
13275         MKDIRS=$(changelog_dump | grep -c "MKDIR")
13276         CLOSES=$(changelog_dump | grep -c "CLOSE")
13277         [ $MKDIRS -eq 1 ] || error "MKDIR changelog mask count $MKDIRS != 1"
13278         [ $CLOSES -eq 3 ] || error "CLOSE changelog mask count $CLOSES != 3"
13279
13280         # verify contents
13281         echo "verifying target fid"
13282         local fidc=$(changelog_extract_field "CREAT" "$tfile" "t=")
13283         local fidf=$($LFS path2fid $DIR/$tdir/pics/zach/$tfile)
13284         [ "$fidc" == "$fidf" ] ||
13285                 error "changelog '$tfile' fid $fidc != file fid $fidf"
13286         echo "verifying parent fid"
13287         # The FID returned from the Changelog may be the directory shard on
13288         # a different MDT, and not the FID returned by path2fid on the parent.
13289         # Instead of comparing FIDs, verify that fid2path(fidp) is correct,
13290         # since this is what will matter when recreating this file in the tree.
13291         local fidp=$(changelog_extract_field "CREAT" "$tfile" "p=")
13292         local pathp=$($LFS fid2path $MOUNT "$fidp")
13293         [ "${pathp%/}" == "$DIR/$tdir/pics/zach" ] ||
13294                 error "changelog fid2path($fidc) $pathp != $DIR/$tdir/pics/zach"
13295
13296         echo "getting records for $cl_user"
13297         changelog_users $SINGLEMDS
13298         local user_rec1=$(changelog_user_rec $SINGLEMDS $cl_user)
13299         local nclr=3
13300         __changelog_clear $SINGLEMDS $cl_user +$nclr ||
13301                 error "changelog_clear failed"
13302         local user_rec2=$(changelog_user_rec $SINGLEMDS $cl_user)
13303         echo "verifying user clear: $user_rec1 + $nclr == $user_rec2"
13304         [ $user_rec2 == $((user_rec1 + nclr)) ] ||
13305                 error "user index expect $user_rec1 + $nclr != $user_rec2"
13306
13307         local min0_rec=$(changelog_users $SINGLEMDS |
13308                 awk 'min == "" || $2 < min { min = $2 }; END { print min }')
13309         local first_rec=$($LFS changelog $(facet_svc $SINGLEMDS) |
13310                           awk '{ print $1; exit; }')
13311
13312         changelog_dump | tail -n 5
13313         echo "verifying user min purge: $min0_rec + 1 == $first_rec"
13314         [ $first_rec == $((min0_rec + 1)) ] ||
13315                 error "first index should be $min0_rec + 1 not $first_rec"
13316
13317         # LU-3446 changelog index reset on MDT restart
13318         local cur_rec1=$(changelog_users $SINGLEMDS |
13319                          awk '/^current.index:/ { print $NF }')
13320         changelog_clear 0 ||
13321                 error "clear all changelog records for $cl_user failed"
13322         stop $SINGLEMDS || error "Fail to stop $SINGLEMDS"
13323         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
13324                 error "Fail to start $SINGLEMDS"
13325         local cur_rec2=$(changelog_users $SINGLEMDS |
13326                          awk '/^current.index:/ { print $NF }')
13327         echo "verifying index survives MDT restart: $cur_rec1 == $cur_rec2"
13328         [ $cur_rec1 == $cur_rec2 ] ||
13329                 error "current index should be $cur_rec1 not $cur_rec2"
13330
13331         echo "verifying users from this test are deregistered"
13332         changelog_deregister || error "changelog_deregister failed"
13333         changelog_users $SINGLEMDS | grep -q $cl_user &&
13334                 error "User '$cl_user' still in changelog_users"
13335
13336         # lctl get_param -n mdd.*.changelog_users
13337         # current index: 144
13338         # ID    index (idle seconds)
13339         # cl3   144 (2)
13340         if ! changelog_users $SINGLEMDS | grep "^cl"; then
13341                 # this is the normal case where all users were deregistered
13342                 # make sure no new records are added when no users are present
13343                 local last_rec1=$(changelog_users $SINGLEMDS |
13344                                   awk '/^current.index:/ { print $NF }')
13345                 touch $DIR/$tdir/chloe
13346                 local last_rec2=$(changelog_users $SINGLEMDS |
13347                                   awk '/^current.index:/ { print $NF }')
13348                 echo "verify changelogs are off: $last_rec1 == $last_rec2"
13349                 [ $last_rec1 == $last_rec2 ] || error "changelogs not off"
13350         else
13351                 # any changelog users must be leftovers from a previous test
13352                 changelog_users $SINGLEMDS
13353                 echo "other changelog users; can't verify off"
13354         fi
13355 }
13356 run_test 160a "changelog sanity"
13357
13358 test_160b() { # LU-3587
13359         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13360         remote_mds_nodsh && skip "remote MDS with nodsh"
13361         [ $MDS1_VERSION -ge $(version_code 2.2.0) ] ||
13362                 skip "Need MDS version at least 2.2.0"
13363
13364         changelog_register || error "changelog_register failed"
13365         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13366         changelog_users $SINGLEMDS | grep -q $cl_user ||
13367                 error "User '$cl_user' not found in changelog_users"
13368
13369         local longname1=$(str_repeat a 255)
13370         local longname2=$(str_repeat b 255)
13371
13372         cd $DIR
13373         echo "creating very long named file"
13374         touch $longname1 || error "create of '$longname1' failed"
13375         echo "renaming very long named file"
13376         mv $longname1 $longname2
13377
13378         changelog_dump | grep RENME | tail -n 5
13379         rm -f $longname2
13380 }
13381 run_test 160b "Verify that very long rename doesn't crash in changelog"
13382
13383 test_160c() {
13384         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13385         remote_mds_nodsh && skip "remote MDS with nodsh"
13386
13387         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
13388                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
13389                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
13390                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
13391
13392         local rc=0
13393
13394         # Registration step
13395         changelog_register || error "changelog_register failed"
13396
13397         rm -rf $DIR/$tdir
13398         mkdir -p $DIR/$tdir
13399         $MCREATE $DIR/$tdir/foo_160c
13400         changelog_chmask "-TRUNC"
13401         $TRUNCATE $DIR/$tdir/foo_160c 200
13402         changelog_chmask "+TRUNC"
13403         $TRUNCATE $DIR/$tdir/foo_160c 199
13404         changelog_dump | tail -n 5
13405         local truncs=$(changelog_dump | tail -n 5 | grep -c TRUNC)
13406         [ $truncs -eq 1 ] || error "TRUNC changelog mask count $truncs != 1"
13407 }
13408 run_test 160c "verify that changelog log catch the truncate event"
13409
13410 test_160d() {
13411         remote_mds_nodsh && skip "remote MDS with nodsh"
13412         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
13413         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13414         [[ $MDS1_VERSION -ge $(version_code 2.7.60) ]] ||
13415                 skip "Need MDS version at least 2.7.60"
13416
13417         # Registration step
13418         changelog_register || error "changelog_register failed"
13419
13420         mkdir -p $DIR/$tdir/migrate_dir
13421         changelog_clear 0 || error "changelog_clear failed"
13422
13423         $LFS migrate -m 1 $DIR/$tdir/migrate_dir || error "migrate fails"
13424         changelog_dump | tail -n 5
13425         local migrates=$(changelog_dump | grep -c "MIGRT")
13426         [ $migrates -eq 1 ] || error "MIGRATE changelog count $migrates != 1"
13427 }
13428 run_test 160d "verify that changelog log catch the migrate event"
13429
13430 test_160e() {
13431         remote_mds_nodsh && skip "remote MDS with nodsh"
13432
13433         # Create a user
13434         changelog_register || error "changelog_register failed"
13435
13436         # Delete a future user (expect fail)
13437         local MDT0=$(facet_svc $SINGLEMDS)
13438         do_facet $SINGLEMDS $LCTL --device $MDT0 changelog_deregister "cl77"
13439         local rc=$?
13440
13441         if [ $rc -eq 0 ]; then
13442                 error "Deleted non-existant user cl77"
13443         elif [ $rc -ne 2 ]; then
13444                 error "changelog_deregister failed with $rc, expect 2 (ENOENT)"
13445         fi
13446
13447         # Clear to a bad index (1 billion should be safe)
13448         $LFS changelog_clear $MDT0 "${CL_USERS[$SINGLEMDS]%% *}" 1000000000
13449         rc=$?
13450
13451         if [ $rc -eq 0 ]; then
13452                 error "Successfully cleared to invalid CL index"
13453         elif [ $rc -ne 22 ]; then
13454                 error "changelog_clear failed with $rc, expected 22 (EINVAL)"
13455         fi
13456 }
13457 run_test 160e "changelog negative testing (should return errors)"
13458
13459 test_160f() {
13460         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13461         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13462                 skip "Need MDS version at least 2.10.56"
13463
13464         local mdts=$(comma_list $(mdts_nodes))
13465
13466         # Create a user
13467         changelog_register || error "first changelog_register failed"
13468         changelog_register || error "second changelog_register failed"
13469         local cl_users
13470         declare -A cl_user1
13471         declare -A cl_user2
13472         local user_rec1
13473         local user_rec2
13474         local i
13475
13476         # generate some changelog records to accumulate on each MDT
13477         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13478         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13479                 error "create $DIR/$tdir/$tfile failed"
13480
13481         # check changelogs have been generated
13482         local nbcl=$(changelog_dump | wc -l)
13483         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13484
13485         for param in "changelog_max_idle_time=10" \
13486                      "changelog_gc=1" \
13487                      "changelog_min_gc_interval=2" \
13488                      "changelog_min_free_cat_entries=3"; do
13489                 local MDT0=$(facet_svc $SINGLEMDS)
13490                 local var="${param%=*}"
13491                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13492
13493                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13494                 do_nodes $mdts $LCTL set_param mdd.*.$param
13495         done
13496
13497         # force cl_user2 to be idle (1st part)
13498         sleep 9
13499
13500         # simulate changelog catalog almost full
13501         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13502         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13503
13504         for i in $(seq $MDSCOUNT); do
13505                 cl_users=(${CL_USERS[mds$i]})
13506                 cl_user1[mds$i]="${cl_users[0]}"
13507                 cl_user2[mds$i]="${cl_users[1]}"
13508
13509                 [ -n "${cl_user1[mds$i]}" ] ||
13510                         error "mds$i: no user registered"
13511                 [ -n "${cl_user2[mds$i]}" ] ||
13512                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13513
13514                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13515                 [ -n "$user_rec1" ] ||
13516                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13517                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13518                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13519                 [ -n "$user_rec2" ] ||
13520                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13521                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13522                      "$user_rec1 + 2 == $user_rec2"
13523                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13524                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13525                               "$user_rec1 + 2, but is $user_rec2"
13526                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13527                 [ -n "$user_rec2" ] ||
13528                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13529                 [ $user_rec1 == $user_rec2 ] ||
13530                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13531                               "$user_rec1, but is $user_rec2"
13532         done
13533
13534         # force cl_user2 to be idle (2nd part) and to reach
13535         # changelog_max_idle_time
13536         sleep 2
13537
13538         # generate one more changelog to trigger fail_loc
13539         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13540                 error "create $DIR/$tdir/${tfile}bis failed"
13541
13542         # ensure gc thread is done
13543         for i in $(mdts_nodes); do
13544                 wait_update $i \
13545                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13546                         error "$i: GC-thread not done"
13547         done
13548
13549         local first_rec
13550         for i in $(seq $MDSCOUNT); do
13551                 # check cl_user1 still registered
13552                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13553                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13554                 # check cl_user2 unregistered
13555                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13556                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13557
13558                 # check changelogs are present and starting at $user_rec1 + 1
13559                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13560                 [ -n "$user_rec1" ] ||
13561                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13562                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13563                             awk '{ print $1; exit; }')
13564
13565                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13566                 [ $((user_rec1 + 1)) == $first_rec ] ||
13567                         error "mds$i: first index should be $user_rec1 + 1, " \
13568                               "but is $first_rec"
13569         done
13570 }
13571 run_test 160f "changelog garbage collect (timestamped users)"
13572
13573 test_160g() {
13574         remote_mds_nodsh && skip "remote MDS with nodsh"
13575         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13576                 skip "Need MDS version at least 2.10.56"
13577
13578         local mdts=$(comma_list $(mdts_nodes))
13579
13580         #define OBD_FAIL_TIME_IN_CHLOG_USER     0x1314
13581         do_nodes $mdts $LCTL set_param fail_loc=0x1314
13582
13583         # Create a user
13584         changelog_register || error "first changelog_register failed"
13585         changelog_register || error "second changelog_register failed"
13586         local cl_users
13587         declare -A cl_user1
13588         declare -A cl_user2
13589         local user_rec1
13590         local user_rec2
13591         local i
13592
13593         # generate some changelog records to accumulate on each MDT
13594         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13595         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13596                 error "create $DIR/$tdir/$tfile failed"
13597
13598         # check changelogs have been generated
13599         local nbcl=$(changelog_dump | wc -l)
13600         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13601
13602         # reduce the max_idle_indexes value to make sure we exceed it
13603         max_ndx=$((nbcl / 2 - 1))
13604
13605         for param in "changelog_max_idle_indexes=$max_ndx" \
13606                      "changelog_gc=1" \
13607                      "changelog_min_gc_interval=2" \
13608                      "changelog_min_free_cat_entries=3"; do
13609                 local MDT0=$(facet_svc $SINGLEMDS)
13610                 local var="${param%=*}"
13611                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13612
13613                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13614                 do_nodes $mdts $LCTL set_param mdd.*.$param ||
13615                         error "unable to set mdd.*.$param"
13616         done
13617
13618         # simulate changelog catalog almost full
13619         #define OBD_FAIL_CAT_FREE_RECORDS       0x1313
13620         do_nodes $mdts $LCTL set_param fail_loc=0x1313 fail_val=3
13621
13622         for i in $(seq $MDSCOUNT); do
13623                 cl_users=(${CL_USERS[mds$i]})
13624                 cl_user1[mds$i]="${cl_users[0]}"
13625                 cl_user2[mds$i]="${cl_users[1]}"
13626
13627                 [ -n "${cl_user1[mds$i]}" ] ||
13628                         error "mds$i: no user registered"
13629                 [ -n "${cl_user2[mds$i]}" ] ||
13630                         error "mds$i: only ${cl_user1[mds$i]} is registered"
13631
13632                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13633                 [ -n "$user_rec1" ] ||
13634                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13635                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13636                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13637                 [ -n "$user_rec2" ] ||
13638                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13639                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13640                      "$user_rec1 + 2 == $user_rec2"
13641                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13642                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13643                               "$user_rec1 + 2, but is $user_rec2"
13644                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13645                 [ -n "$user_rec2" ] ||
13646                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13647                 [ $user_rec1 == $user_rec2 ] ||
13648                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13649                               "$user_rec1, but is $user_rec2"
13650         done
13651
13652         # ensure we are past the previous changelog_min_gc_interval set above
13653         sleep 2
13654
13655         # generate one more changelog to trigger fail_loc
13656         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13657                 error "create $DIR/$tdir/${tfile}bis failed"
13658
13659         # ensure gc thread is done
13660         for i in $(mdts_nodes); do
13661                 wait_update $i \
13662                         "ps -e -o comm= | grep chlg_gc_thread" "" 20 ||
13663                         error "$i: GC-thread not done"
13664         done
13665
13666         local first_rec
13667         for i in $(seq $MDSCOUNT); do
13668                 # check cl_user1 still registered
13669                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13670                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13671                 # check cl_user2 unregistered
13672                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13673                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13674
13675                 # check changelogs are present and starting at $user_rec1 + 1
13676                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13677                 [ -n "$user_rec1" ] ||
13678                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13679                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13680                             awk '{ print $1; exit; }')
13681
13682                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13683                 [ $((user_rec1 + 1)) == $first_rec ] ||
13684                         error "mds$i: first index should be $user_rec1 + 1, " \
13685                               "but is $first_rec"
13686         done
13687 }
13688 run_test 160g "changelog garbage collect (old users)"
13689
13690 test_160h() {
13691         remote_mds_nodsh && skip "remote MDS with nodsh" && return
13692         [[ $MDS1_VERSION -ge $(version_code 2.10.56) ]] ||
13693                 skip "Need MDS version at least 2.10.56"
13694
13695         local mdts=$(comma_list $(mdts_nodes))
13696
13697         # Create a user
13698         changelog_register || error "first changelog_register failed"
13699         changelog_register || error "second changelog_register failed"
13700         local cl_users
13701         declare -A cl_user1
13702         declare -A cl_user2
13703         local user_rec1
13704         local user_rec2
13705         local i
13706
13707         # generate some changelog records to accumulate on each MDT
13708         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "test_mkdir $tdir failed"
13709         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13710                 error "create $DIR/$tdir/$tfile failed"
13711
13712         # check changelogs have been generated
13713         local nbcl=$(changelog_dump | wc -l)
13714         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13715
13716         for param in "changelog_max_idle_time=10" \
13717                      "changelog_gc=1" \
13718                      "changelog_min_gc_interval=2"; do
13719                 local MDT0=$(facet_svc $SINGLEMDS)
13720                 local var="${param%=*}"
13721                 local old=$(do_facet mds1 "$LCTL get_param -n mdd.$MDT0.$var")
13722
13723                 stack_trap "do_nodes $mdts $LCTL set_param mdd.*.$var=$old" EXIT
13724                 do_nodes $mdts $LCTL set_param mdd.*.$param
13725         done
13726
13727         # force cl_user2 to be idle (1st part)
13728         sleep 9
13729
13730         for i in $(seq $MDSCOUNT); do
13731                 cl_users=(${CL_USERS[mds$i]})
13732                 cl_user1[mds$i]="${cl_users[0]}"
13733                 cl_user2[mds$i]="${cl_users[1]}"
13734
13735                 [ -n "${cl_user1[mds$i]}" ] ||
13736                         error "mds$i: no user registered"
13737                 [ -n "${cl_user2[mds$i]}" ] ||
13738                         error "mds$i: only ${cl_user2[mds$i]} is registered"
13739
13740                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13741                 [ -n "$user_rec1" ] ||
13742                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13743                 __changelog_clear mds$i ${cl_user1[mds$i]} +2
13744                 user_rec2=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13745                 [ -n "$user_rec2" ] ||
13746                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13747                 echo "mds$i: verifying user ${cl_user1[mds$i]} clear: " \
13748                      "$user_rec1 + 2 == $user_rec2"
13749                 [ $((user_rec1 + 2)) == $user_rec2 ] ||
13750                         error "mds$i: user ${cl_user1[mds$i]} index expected " \
13751                               "$user_rec1 + 2, but is $user_rec2"
13752                 user_rec2=$(changelog_user_rec mds$i ${cl_user2[mds$i]})
13753                 [ -n "$user_rec2" ] ||
13754                         error "mds$i: User ${cl_user2[mds$i]} not registered"
13755                 [ $user_rec1 == $user_rec2 ] ||
13756                         error "mds$i: user ${cl_user2[mds$i]} index expected " \
13757                               "$user_rec1, but is $user_rec2"
13758         done
13759
13760         # force cl_user2 to be idle (2nd part) and to reach
13761         # changelog_max_idle_time
13762         sleep 2
13763
13764         # force each GC-thread start and block then
13765         # one per MDT/MDD, set fail_val accordingly
13766         #define OBD_FAIL_FORCE_GC_THREAD 0x1316
13767         do_nodes $mdts $LCTL set_param fail_loc=0x1316
13768
13769         # generate more changelogs to trigger fail_loc
13770         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13771                 error "create $DIR/$tdir/${tfile}bis failed"
13772
13773         # stop MDT to stop GC-thread, should be done in back-ground as it will
13774         # block waiting for the thread to be released and exit
13775         declare -A stop_pids
13776         for i in $(seq $MDSCOUNT); do
13777                 stop mds$i &
13778                 stop_pids[mds$i]=$!
13779         done
13780
13781         for i in $(mdts_nodes); do
13782                 local facet
13783                 local nb=0
13784                 local facets=$(facets_up_on_host $i)
13785
13786                 for facet in ${facets//,/ }; do
13787                         if [[ $facet == mds* ]]; then
13788                                 nb=$((nb + 1))
13789                         fi
13790                 done
13791                 # ensure each MDS's gc threads are still present and all in "R"
13792                 # state (OBD_FAIL_FORCE_GC_THREAD effect!)
13793                 [[ $(do_node $i pgrep chlg_gc_thread | wc -l) -eq $nb ]] ||
13794                         error "$i: expected $nb GC-thread"
13795                 wait_update $i \
13796                         "ps -C chlg_gc_thread -o state --no-headers | uniq" \
13797                         "R" 20 ||
13798                         error "$i: GC-thread not found in R-state"
13799                 # check umounts of each MDT on MDS have reached kthread_stop()
13800                 [[ $(do_node $i pgrep umount | wc -l) -eq $nb ]] ||
13801                         error "$i: expected $nb umount"
13802                 wait_update $i \
13803                         "ps -C umount -o state --no-headers | uniq" "D" 20 ||
13804                         error "$i: umount not found in D-state"
13805         done
13806
13807         # release all GC-threads
13808         do_nodes $mdts $LCTL set_param fail_loc=0
13809
13810         # wait for MDT stop to complete
13811         for i in $(seq $MDSCOUNT); do
13812                 wait ${stop_pids[mds$i]} || error "mds$i: stop failed"
13813         done
13814
13815         # XXX
13816         # may try to check if any orphan changelog records are present
13817         # via ldiskfs/zfs and llog_reader...
13818
13819         # re-start/mount MDTs
13820         for i in $(seq $MDSCOUNT); do
13821                 start mds$i $(mdsdevname $i) $MDS_MOUNT_OPTS ||
13822                         error "Fail to start mds$i"
13823         done
13824
13825         local first_rec
13826         for i in $(seq $MDSCOUNT); do
13827                 # check cl_user1 still registered
13828                 changelog_users mds$i | grep -q "${cl_user1[mds$i]}" ||
13829                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13830                 # check cl_user2 unregistered
13831                 changelog_users mds$i | grep -q "${cl_user2[mds$i]}" &&
13832                         error "mds$i: User ${cl_user2[mds$i]} still registered"
13833
13834                 # check changelogs are present and starting at $user_rec1 + 1
13835                 user_rec1=$(changelog_user_rec mds$i ${cl_user1[mds$i]})
13836                 [ -n "$user_rec1" ] ||
13837                         error "mds$i: User ${cl_user1[mds$i]} not registered"
13838                 first_rec=$($LFS changelog $(facet_svc mds$i) |
13839                             awk '{ print $1; exit; }')
13840
13841                 echo "mds$i: verifying first index $user_rec1 + 1 == $first_rec"
13842                 [ $((user_rec1 + 1)) == $first_rec ] ||
13843                         error "mds$i: first index should be $user_rec1 + 1, " \
13844                               "but is $first_rec"
13845         done
13846 }
13847 run_test 160h "changelog gc thread stop upon umount, orphan records delete " \
13848               "during mount"
13849
13850 test_160i() {
13851
13852         local mdts=$(comma_list $(mdts_nodes))
13853
13854         changelog_register || error "first changelog_register failed"
13855
13856         # generate some changelog records to accumulate on each MDT
13857         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13858         createmany -m $DIR/$tdir/$tfile $((MDSCOUNT * 2)) ||
13859                 error "create $DIR/$tdir/$tfile failed"
13860
13861         # check changelogs have been generated
13862         local nbcl=$(changelog_dump | wc -l)
13863         [[ $nbcl -eq 0 ]] && error "no changelogs found"
13864
13865         # simulate race between register and unregister
13866         # XXX as fail_loc is set per-MDS, with DNE configs the race
13867         # simulation will only occur for one MDT per MDS and for the
13868         # others the normal race scenario will take place
13869         #define CFS_FAIL_CHLOG_USER_REG_UNREG_RACE          0x1315
13870         do_nodes $mdts $LCTL set_param fail_loc=0x10001315
13871         do_nodes $mdts $LCTL set_param fail_val=1
13872
13873         # unregister 1st user
13874         changelog_deregister &
13875         local pid1=$!
13876         # wait some time for deregister work to reach race rdv
13877         sleep 2
13878         # register 2nd user
13879         changelog_register || error "2nd user register failed"
13880
13881         wait $pid1 || error "1st user deregister failed"
13882
13883         local i
13884         local last_rec
13885         declare -A LAST_REC
13886         for i in $(seq $MDSCOUNT); do
13887                 if changelog_users mds$i | grep "^cl"; then
13888                         # make sure new records are added with one user present
13889                         LAST_REC[mds$i]=$(changelog_users $SINGLEMDS |
13890                                           awk '/^current.index:/ { print $NF }')
13891                 else
13892                         error "mds$i has no user registered"
13893                 fi
13894         done
13895
13896         # generate more changelog records to accumulate on each MDT
13897         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13898                 error "create $DIR/$tdir/${tfile}bis failed"
13899
13900         for i in $(seq $MDSCOUNT); do
13901                 last_rec=$(changelog_users $SINGLEMDS |
13902                            awk '/^current.index:/ { print $NF }')
13903                 echo "verify changelogs are on: $last_rec != ${LAST_REC[mds$i]}"
13904                 [ $last_rec != ${LAST_REC[mds$i]} ] ||
13905                         error "changelogs are off on mds$i"
13906         done
13907 }
13908 run_test 160i "changelog user register/unregister race"
13909
13910 test_160j() {
13911         remote_mds_nodsh && skip "remote MDS with nodsh"
13912         [[ $MDS1_VERSION -lt $(version_code 2.12.56) ]] &&
13913                 skip "Need MDS version at least 2.12.56"
13914
13915         mount_client $MOUNT2 || error "mount_client on $MOUNT2 failed"
13916
13917         changelog_register || error "first changelog_register failed"
13918
13919         # generate some changelog
13920         test_mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
13921         createmany -m $DIR/$tdir/${tfile}bis $((MDSCOUNT * 2)) ||
13922                 error "create $DIR/$tdir/${tfile}bis failed"
13923
13924         # open the changelog device
13925         exec 3>/dev/changelog-$FSNAME-MDT0000
13926         exec 4</dev/changelog-$FSNAME-MDT0000
13927
13928         # umount the first lustre mount
13929         umount $MOUNT
13930
13931         # read changelog
13932         cat <&4 >/dev/null || error "read changelog failed"
13933
13934         # clear changelog
13935         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
13936         changelog_users $SINGLEMDS | grep -q $cl_user ||
13937                 error "User $cl_user not found in changelog_users"
13938
13939         printf 'clear:'$cl_user':0' >&3
13940
13941         # close
13942         exec 3>&-
13943         exec 4<&-
13944
13945         # cleanup
13946         changelog_deregister || error "changelog_deregister failed"
13947
13948         umount $MOUNT2
13949         mount_client $MOUNT || error "mount_client on $MOUNT failed"
13950 }
13951 run_test 160j "client can be umounted  while its chanangelog is being used"
13952
13953 test_161a() {
13954         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13955
13956         test_mkdir -c1 $DIR/$tdir
13957         cp /etc/hosts $DIR/$tdir/$tfile
13958         test_mkdir -c1 $DIR/$tdir/foo1
13959         test_mkdir -c1 $DIR/$tdir/foo2
13960         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/sofia
13961         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/zachary
13962         ln $DIR/$tdir/$tfile $DIR/$tdir/foo1/luna
13963         ln $DIR/$tdir/$tfile $DIR/$tdir/foo2/thor
13964         local FID=$($LFS path2fid $DIR/$tdir/$tfile | tr -d '[]')
13965         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
13966                 $LFS fid2path $DIR $FID
13967                 error "bad link ea"
13968         fi
13969         # middle
13970         rm $DIR/$tdir/foo2/zachary
13971         # last
13972         rm $DIR/$tdir/foo2/thor
13973         # first
13974         rm $DIR/$tdir/$tfile
13975         # rename
13976         mv $DIR/$tdir/foo1/sofia $DIR/$tdir/foo2/maggie
13977         [ "$($LFS fid2path $FSNAME --link 1 $FID)" != "$tdir/foo2/maggie" ] &&
13978                 { $LFS fid2path $DIR $FID; error "bad link rename"; }
13979         rm $DIR/$tdir/foo2/maggie
13980
13981         # overflow the EA
13982         local longname=$tfile.avg_len_is_thirty_two_
13983         stack_trap "unlinkmany $DIR/$tdir/foo2/$longname 1000 || \
13984                 error_noexit 'failed to unlink many hardlinks'" EXIT
13985         createmany -l$DIR/$tdir/foo1/luna $DIR/$tdir/foo2/$longname 1000 ||
13986                 error "failed to hardlink many files"
13987         links=$($LFS fid2path $DIR $FID | wc -l)
13988         echo -n "${links}/1000 links in link EA"
13989         [[ $links -gt 60 ]] || error "expected at least 60 links in link EA"
13990 }
13991 run_test 161a "link ea sanity"
13992
13993 test_161b() {
13994         [ $PARALLEL == "yes" ] && skip "skip parallel run"
13995         [ $MDSCOUNT -lt 2 ] && skip_env "skipping remote directory test"
13996
13997         local MDTIDX=1
13998         local remote_dir=$DIR/$tdir/remote_dir
13999
14000         mkdir -p $DIR/$tdir
14001         $LFS mkdir -i $MDTIDX $remote_dir ||
14002                 error "create remote directory failed"
14003
14004         cp /etc/hosts $remote_dir/$tfile
14005         mkdir -p $remote_dir/foo1
14006         mkdir -p $remote_dir/foo2
14007         ln $remote_dir/$tfile $remote_dir/foo1/sofia
14008         ln $remote_dir/$tfile $remote_dir/foo2/zachary
14009         ln $remote_dir/$tfile $remote_dir/foo1/luna
14010         ln $remote_dir/$tfile $remote_dir/foo2/thor
14011
14012         local FID=$($LFS path2fid $remote_dir/$tfile | tr -d '[' |
14013                      tr -d ']')
14014         if [ "$($LFS fid2path $DIR $FID | wc -l)" != "5" ]; then
14015                 $LFS fid2path $DIR $FID
14016                 error "bad link ea"
14017         fi
14018         # middle
14019         rm $remote_dir/foo2/zachary
14020         # last
14021         rm $remote_dir/foo2/thor
14022         # first
14023         rm $remote_dir/$tfile
14024         # rename
14025         mv $remote_dir/foo1/sofia $remote_dir/foo2/maggie
14026         local link_path=$($LFS fid2path $FSNAME --link 1 $FID)
14027         if [ "$DIR/$link_path" != "$remote_dir/foo2/maggie" ]; then
14028                 $LFS fid2path $DIR $FID
14029                 error "bad link rename"
14030         fi
14031         rm $remote_dir/foo2/maggie
14032
14033         # overflow the EA
14034         local longname=filename_avg_len_is_thirty_two_
14035         createmany -l$remote_dir/foo1/luna $remote_dir/foo2/$longname 1000 ||
14036                 error "failed to hardlink many files"
14037         links=$($LFS fid2path $DIR $FID | wc -l)
14038         echo -n "${links}/1000 links in link EA"
14039         [[ ${links} -gt 60 ]] ||
14040                 error "expected at least 60 links in link EA"
14041         unlinkmany $remote_dir/foo2/$longname 1000 ||
14042         error "failed to unlink many hardlinks"
14043 }
14044 run_test 161b "link ea sanity under remote directory"
14045
14046 test_161c() {
14047         remote_mds_nodsh && skip "remote MDS with nodsh"
14048         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14049         [[ $MDS1_VERSION -lt $(version_code 2.1.5) ]] &&
14050                 skip "Need MDS version at least 2.1.5"
14051
14052         # define CLF_RENAME_LAST 0x0001
14053         # rename overwrite a target having nlink = 1 (changelog flag 0x1)
14054         changelog_register || error "changelog_register failed"
14055
14056         rm -rf $DIR/$tdir
14057         test_mkdir -i $((MDSCOUNT - 1)) $DIR/$tdir
14058         touch $DIR/$tdir/foo_161c
14059         touch $DIR/$tdir/bar_161c
14060         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14061         changelog_dump | grep RENME | tail -n 5
14062         local flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14063         changelog_clear 0 || error "changelog_clear failed"
14064         if [ x$flags != "x0x1" ]; then
14065                 error "flag $flags is not 0x1"
14066         fi
14067
14068         echo "rename overwrite target with nlink = 1, changelog flags=$flags"
14069         # rename overwrite a target having nlink > 1 (changelog flag 0x0)
14070         touch $DIR/$tdir/foo_161c
14071         touch $DIR/$tdir/bar_161c
14072         ln $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14073         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/bar_161c
14074         changelog_dump | grep RENME | tail -n 5
14075         flags=$(changelog_dump | grep "RENME.*bar_161c" | cut -f5 -d' ')
14076         changelog_clear 0 || error "changelog_clear failed"
14077         if [ x$flags != "x0x0" ]; then
14078                 error "flag $flags is not 0x0"
14079         fi
14080         echo "rename overwrite a target having nlink > 1," \
14081                 "changelog record has flags of $flags"
14082
14083         # rename doesn't overwrite a target (changelog flag 0x0)
14084         touch $DIR/$tdir/foo_161c
14085         mv -f $DIR/$tdir/foo_161c $DIR/$tdir/foo2_161c
14086         changelog_dump | grep RENME | tail -n 5
14087         flags=$(changelog_dump | grep RENME | tail -1 | cut -f5 -d' ')
14088         changelog_clear 0 || error "changelog_clear failed"
14089         if [ x$flags != "x0x0" ]; then
14090                 error "flag $flags is not 0x0"
14091         fi
14092         echo "rename doesn't overwrite a target," \
14093                 "changelog record has flags of $flags"
14094
14095         # define CLF_UNLINK_LAST 0x0001
14096         # unlink a file having nlink = 1 (changelog flag 0x1)
14097         rm -f $DIR/$tdir/foo2_161c
14098         changelog_dump | grep UNLNK | tail -n 5
14099         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14100         changelog_clear 0 || error "changelog_clear failed"
14101         if [ x$flags != "x0x1" ]; then
14102                 error "flag $flags is not 0x1"
14103         fi
14104         echo "unlink a file having nlink = 1," \
14105                 "changelog record has flags of $flags"
14106
14107         # unlink a file having nlink > 1 (changelog flag 0x0)
14108         ln -f $DIR/$tdir/bar_161c $DIR/$tdir/foobar_161c
14109         rm -f $DIR/$tdir/foobar_161c
14110         changelog_dump | grep UNLNK | tail -n 5
14111         flags=$(changelog_dump | grep UNLNK | tail -1 | cut -f5 -d' ')
14112         changelog_clear 0 || error "changelog_clear failed"
14113         if [ x$flags != "x0x0" ]; then
14114                 error "flag $flags is not 0x0"
14115         fi
14116         echo "unlink a file having nlink > 1, changelog record flags '$flags'"
14117 }
14118 run_test 161c "check CL_RENME[UNLINK] changelog record flags"
14119
14120 test_161d() {
14121         remote_mds_nodsh && skip "remote MDS with nodsh"
14122         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
14123
14124         local pid
14125         local fid
14126
14127         changelog_register || error "changelog_register failed"
14128
14129         # work in a standalone dir to avoid locking on $DIR/$MOUNT to
14130         # interfer with $MOUNT/.lustre/fid/ access
14131         mkdir $DIR/$tdir
14132         [[ $? -eq 0 ]] || error "mkdir failed"
14133
14134         #define OBD_FAIL_LLITE_CREATE_NODE_PAUSE 0x140c | OBD_FAIL_ONCE
14135         $LCTL set_param fail_loc=0x8000140c
14136         # 5s pause
14137         $LCTL set_param fail_val=5
14138
14139         # create file
14140         echo foofoo > $DIR/$tdir/$tfile &
14141         pid=$!
14142
14143         # wait for create to be delayed
14144         sleep 2
14145
14146         ps -p $pid
14147         [[ $? -eq 0 ]] || error "create should be blocked"
14148
14149         local tempfile="$(mktemp --tmpdir $tfile.XXXXXX)"
14150         stack_trap "rm -f $tempfile"
14151         fid=$(changelog_extract_field "CREAT" "$tfile" "t=")
14152         cat $MOUNT/.lustre/fid/$fid 2>/dev/null >$tempfile || error "cat failed"
14153         # some delay may occur during ChangeLog publishing and file read just
14154         # above, that could allow file write to happen finally
14155         [[ -s $tempfile ]] && echo "file should be empty"
14156
14157         $LCTL set_param fail_loc=0
14158
14159         wait $pid
14160         [[ $? -eq 0 ]] || error "create failed"
14161 }
14162 run_test 161d "create with concurrent .lustre/fid access"
14163
14164 check_path() {
14165         local expected="$1"
14166         shift
14167         local fid="$2"
14168
14169         local path
14170         path=$($LFS fid2path "$@")
14171         local rc=$?
14172
14173         if [ $rc -ne 0 ]; then
14174                 error "path looked up of '$expected' failed: rc=$rc"
14175         elif [ "$path" != "$expected" ]; then
14176                 error "path looked up '$path' instead of '$expected'"
14177         else
14178                 echo "FID '$fid' resolves to path '$path' as expected"
14179         fi
14180 }
14181
14182 test_162a() { # was test_162
14183         test_mkdir -p -c1 $DIR/$tdir/d2
14184         touch $DIR/$tdir/d2/$tfile
14185         touch $DIR/$tdir/d2/x1
14186         touch $DIR/$tdir/d2/x2
14187         test_mkdir -p -c1 $DIR/$tdir/d2/a/b/c
14188         test_mkdir -p -c1 $DIR/$tdir/d2/p/q/r
14189         # regular file
14190         local fid=$($LFS path2fid $DIR/$tdir/d2/$tfile | tr -d '[]')
14191         check_path "$tdir/d2/$tfile" $FSNAME "$fid" --link 0
14192
14193         # softlink
14194         ln -s $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/slink
14195         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink | tr -d '[]')
14196         check_path "$tdir/d2/p/q/r/slink" $FSNAME "$fid" --link 0
14197
14198         # softlink to wrong file
14199         ln -s /this/is/garbage $DIR/$tdir/d2/p/q/r/slink.wrong
14200         fid=$($LFS path2fid $DIR/$tdir/d2/p/q/r/slink.wrong | tr -d '[]')
14201         check_path "$tdir/d2/p/q/r/slink.wrong" $FSNAME "$fid" --link 0
14202
14203         # hardlink
14204         ln $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/p/q/r/hlink
14205         mv $DIR/$tdir/d2/$tfile $DIR/$tdir/d2/a/b/c/new_file
14206         fid=$($LFS path2fid $DIR/$tdir/d2/a/b/c/new_file | tr -d '[]')
14207         # fid2path dir/fsname should both work
14208         check_path "$tdir/d2/a/b/c/new_file" $FSNAME "$fid" --link 1
14209         check_path "$DIR/$tdir/d2/p/q/r/hlink" $DIR "$fid" --link 0
14210
14211         # hardlink count: check that there are 2 links
14212         local nlinks=$($LFS fid2path $DIR "$fid" | wc -l)
14213         [ $nlinks -eq 2 ] || error "expect 2 links, found $nlinks"
14214
14215         # hardlink indexing: remove the first link
14216         rm $DIR/$tdir/d2/p/q/r/hlink
14217         check_path "$tdir/d2/a/b/c/new_file" $FSNAME $fid --link 0
14218 }
14219 run_test 162a "path lookup sanity"
14220
14221 test_162b() {
14222         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14223         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
14224
14225         mkdir $DIR/$tdir
14226         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
14227                                 error "create striped dir failed"
14228
14229         local FID=$($LFS getdirstripe $DIR/$tdir/striped_dir |
14230                                         tail -n 1 | awk '{print $2}')
14231         stat $MOUNT/.lustre/fid/$FID && error "sub_stripe can be accessed"
14232
14233         touch $DIR/$tdir/striped_dir/f{0..4} || error "touch f0..4 failed"
14234         mkdir $DIR/$tdir/striped_dir/d{0..4} || error "mkdir d0..4 failed"
14235
14236         # regular file
14237         for ((i=0;i<5;i++)); do
14238                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/f$i | tr -d '[]') ||
14239                         error "get fid for f$i failed"
14240                 check_path "$tdir/striped_dir/f$i" $FSNAME $FID --link 0
14241
14242                 FID=$($LFS path2fid $DIR/$tdir/striped_dir/d$i | tr -d '[]') ||
14243                         error "get fid for d$i failed"
14244                 check_path "$tdir/striped_dir/d$i" $FSNAME $FID --link 0
14245         done
14246
14247         return 0
14248 }
14249 run_test 162b "striped directory path lookup sanity"
14250
14251 # LU-4239: Verify fid2path works with paths 100 or more directories deep
14252 test_162c() {
14253         [[ $MDS1_VERSION -lt $(version_code 2.7.51) ]] &&
14254                 skip "Need MDS version at least 2.7.51"
14255
14256         local lpath=$tdir.local
14257         local rpath=$tdir.remote
14258
14259         test_mkdir $DIR/$lpath
14260         test_mkdir $DIR/$rpath
14261
14262         for ((i = 0; i <= 101; i++)); do
14263                 lpath="$lpath/$i"
14264                 mkdir $DIR/$lpath
14265                 FID=$($LFS path2fid $DIR/$lpath | tr -d '[]') ||
14266                         error "get fid for local directory $DIR/$lpath failed"
14267                 check_path "$DIR/$lpath" $MOUNT $FID --link 0
14268
14269                 rpath="$rpath/$i"
14270                 test_mkdir $DIR/$rpath
14271                 FID=$($LFS path2fid $DIR/$rpath | tr -d '[]') ||
14272                         error "get fid for remote directory $DIR/$rpath failed"
14273                 check_path "$DIR/$rpath" $MOUNT $FID --link 0
14274         done
14275
14276         return 0
14277 }
14278 run_test 162c "fid2path works with paths 100 or more directories deep"
14279
14280 test_169() {
14281         # do directio so as not to populate the page cache
14282         log "creating a 10 Mb file"
14283         $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
14284         log "starting reads"
14285         dd if=$DIR/$tfile of=/dev/null bs=4096 &
14286         log "truncating the file"
14287         $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
14288         log "killing dd"
14289         kill %+ || true # reads might have finished
14290         echo "wait until dd is finished"
14291         wait
14292         log "removing the temporary file"
14293         rm -rf $DIR/$tfile || error "tmp file removal failed"
14294 }
14295 run_test 169 "parallel read and truncate should not deadlock"
14296
14297 test_170() {
14298         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14299
14300         $LCTL clear     # bug 18514
14301         $LCTL debug_daemon start $TMP/${tfile}_log_good
14302         touch $DIR/$tfile
14303         $LCTL debug_daemon stop
14304         sed -e "s/^...../a/g" $TMP/${tfile}_log_good > $TMP/${tfile}_log_bad ||
14305                 error "sed failed to read log_good"
14306
14307         $LCTL debug_daemon start $TMP/${tfile}_log_good
14308         rm -rf $DIR/$tfile
14309         $LCTL debug_daemon stop
14310
14311         $LCTL df $TMP/${tfile}_log_bad > $TMP/${tfile}_log_bad.out 2>&1 ||
14312                error "lctl df log_bad failed"
14313
14314         local bad_line=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14315         local good_line1=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14316
14317         $LCTL df $TMP/${tfile}_log_good > $TMP/${tfile}_log_good.out 2>&1
14318         local good_line2=$(tail -n 1 $TMP/${tfile}_log_good.out | awk '{print $5}')
14319
14320         [ "$bad_line" ] && [ "$good_line1" ] && [ "$good_line2" ] ||
14321                 error "bad_line good_line1 good_line2 are empty"
14322
14323         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14324         cat $TMP/${tfile}_log_bad >> $TMP/${tfile}_logs_corrupt
14325         cat $TMP/${tfile}_log_good >> $TMP/${tfile}_logs_corrupt
14326
14327         $LCTL df $TMP/${tfile}_logs_corrupt > $TMP/${tfile}_log_bad.out 2>&1
14328         local bad_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $9}')
14329         local good_line_new=$(tail -n 1 $TMP/${tfile}_log_bad.out | awk '{print $5}')
14330
14331         [ "$bad_line_new" ] && [ "$good_line_new" ] ||
14332                 error "bad_line_new good_line_new are empty"
14333
14334         local expected_good=$((good_line1 + good_line2*2))
14335
14336         rm -f $TMP/${tfile}*
14337         # LU-231, short malformed line may not be counted into bad lines
14338         if [ $bad_line -ne $bad_line_new ] &&
14339                    [ $bad_line -ne $((bad_line_new - 1)) ]; then
14340                 error "expected $bad_line bad lines, but got $bad_line_new"
14341                 return 1
14342         fi
14343
14344         if [ $expected_good -ne $good_line_new ]; then
14345                 error "expected $expected_good good lines, but got $good_line_new"
14346                 return 2
14347         fi
14348         true
14349 }
14350 run_test 170 "test lctl df to handle corrupted log ====================="
14351
14352 test_171() { # bug20592
14353         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14354
14355         #define OBD_FAIL_PTLRPC_DUMP_LOG         0x50e
14356         $LCTL set_param fail_loc=0x50e
14357         $LCTL set_param fail_val=3000
14358         multiop_bg_pause $DIR/$tfile O_s || true
14359         local MULTIPID=$!
14360         kill -USR1 $MULTIPID
14361         # cause log dump
14362         sleep 3
14363         wait $MULTIPID
14364         if dmesg | grep "recursive fault"; then
14365                 error "caught a recursive fault"
14366         fi
14367         $LCTL set_param fail_loc=0
14368         true
14369 }
14370 run_test 171 "test libcfs_debug_dumplog_thread stuck in do_exit() ======"
14371
14372 # it would be good to share it with obdfilter-survey/iokit-libecho code
14373 setup_obdecho_osc () {
14374         local rc=0
14375         local ost_nid=$1
14376         local obdfilter_name=$2
14377         echo "Creating new osc for $obdfilter_name on $ost_nid"
14378         # make sure we can find loopback nid
14379         $LCTL add_uuid $ost_nid $ost_nid >/dev/null 2>&1
14380
14381         [ $rc -eq 0 ] && { $LCTL attach osc ${obdfilter_name}_osc     \
14382                            ${obdfilter_name}_osc_UUID || rc=2; }
14383         [ $rc -eq 0 ] && { $LCTL --device ${obdfilter_name}_osc setup \
14384                            ${obdfilter_name}_UUID  $ost_nid || rc=3; }
14385         return $rc
14386 }
14387
14388 cleanup_obdecho_osc () {
14389         local obdfilter_name=$1
14390         $LCTL --device ${obdfilter_name}_osc cleanup >/dev/null
14391         $LCTL --device ${obdfilter_name}_osc detach  >/dev/null
14392         return 0
14393 }
14394
14395 obdecho_test() {
14396         local OBD=$1
14397         local node=$2
14398         local pages=${3:-64}
14399         local rc=0
14400         local id
14401
14402         local count=10
14403         local obd_size=$(get_obd_size $node $OBD)
14404         local page_size=$(get_page_size $node)
14405         if [[ -n "$obd_size" ]]; then
14406                 local new_count=$((obd_size / (pages * page_size / 1024)))
14407                 [[ $new_count -ge $count ]] || count=$new_count
14408         fi
14409
14410         do_facet $node "$LCTL attach echo_client ec ec_uuid" || rc=1
14411         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec setup $OBD" ||
14412                            rc=2; }
14413         if [ $rc -eq 0 ]; then
14414             id=$(do_facet $node "$LCTL --device ec create 1"  | awk '/object id/ {print $6}')
14415             [ ${PIPESTATUS[0]} -eq 0 -a -n "$id" ] || rc=3
14416         fi
14417         echo "New object id is $id"
14418         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec getattr $id" ||
14419                            rc=4; }
14420         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec "                 \
14421                            "test_brw $count w v $pages $id" || rc=4; }
14422         [ $rc -eq 0 ] && { do_facet $node "$LCTL --device ec destroy $id 1" ||
14423                            rc=4; }
14424         [ $rc -eq 0 ] || [ $rc -gt 2 ] &&
14425                 { do_facet $node "$LCTL --device ec cleanup" || rc=5; }
14426         [ $rc -eq 0 ] || [ $rc -gt 1 ] &&
14427                 { do_facet $node "$LCTL --device ec detach" || rc=6; }
14428         [ $rc -ne 0 ] && echo "obecho_create_test failed: $rc"
14429         return $rc
14430 }
14431
14432 test_180a() {
14433         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14434
14435         if ! module_loaded obdecho; then
14436                 load_module obdecho/obdecho &&
14437                         stack_trap "rmmod obdecho" EXIT ||
14438                         error "unable to load obdecho on client"
14439         fi
14440
14441         local osc=$($LCTL dl | grep -v mdt | awk '$3 == "osc" {print $4; exit}')
14442         local host=$($LCTL get_param -n osc.$osc.import |
14443                      awk '/current_connection:/ { print $2 }' )
14444         local target=$($LCTL get_param -n osc.$osc.import |
14445                        awk '/target:/ { print $2 }' )
14446         target=${target%_UUID}
14447
14448         if [ -n "$target" ]; then
14449                 setup_obdecho_osc $host $target &&
14450                         stack_trap "cleanup_obdecho_osc $target" EXIT ||
14451                         { error "obdecho setup failed with $?"; return; }
14452
14453                 obdecho_test ${target}_osc client ||
14454                         error "obdecho_test failed on ${target}_osc"
14455         else
14456                 $LCTL get_param osc.$osc.import
14457                 error "there is no osc.$osc.import target"
14458         fi
14459 }
14460 run_test 180a "test obdecho on osc"
14461
14462 test_180b() {
14463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14464         remote_ost_nodsh && skip "remote OST with nodsh"
14465
14466         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14467                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14468                 error "failed to load module obdecho"
14469
14470         local target=$(do_facet ost1 $LCTL dl |
14471                        awk '/obdfilter/ { print $4; exit; }')
14472
14473         if [ -n "$target" ]; then
14474                 obdecho_test $target ost1 || error "obdecho_test failed with $?"
14475         else
14476                 do_facet ost1 $LCTL dl
14477                 error "there is no obdfilter target on ost1"
14478         fi
14479 }
14480 run_test 180b "test obdecho directly on obdfilter"
14481
14482 test_180c() { # LU-2598
14483         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14484         remote_ost_nodsh && skip "remote OST with nodsh"
14485         [[ $MDS1_VERSION -lt $(version_code 2.4.0) ]] &&
14486                 skip "Need MDS version at least 2.4.0"
14487
14488         do_rpc_nodes $(facet_active_host ost1) load_module obdecho/obdecho &&
14489                 stack_trap "do_facet ost1 rmmod obdecho" EXIT ||
14490                 error "failed to load module obdecho"
14491
14492         local target=$(do_facet ost1 $LCTL dl |
14493                        awk '/obdfilter/ { print $4; exit; }')
14494
14495         if [ -n "$target" ]; then
14496                 local pages=16384 # 64MB bulk I/O RPC size
14497
14498                 obdecho_test "$target" ost1 "$pages" ||
14499                         error "obdecho_test with pages=$pages failed with $?"
14500         else
14501                 do_facet ost1 $LCTL dl
14502                 error "there is no obdfilter target on ost1"
14503         fi
14504 }
14505 run_test 180c "test huge bulk I/O size on obdfilter, don't LASSERT"
14506
14507 test_181() { # bug 22177
14508         test_mkdir $DIR/$tdir
14509         # create enough files to index the directory
14510         createmany -o $DIR/$tdir/foobar 4000
14511         # print attributes for debug purpose
14512         lsattr -d .
14513         # open dir
14514         multiop_bg_pause $DIR/$tdir D_Sc || return 1
14515         MULTIPID=$!
14516         # remove the files & current working dir
14517         unlinkmany $DIR/$tdir/foobar 4000
14518         rmdir $DIR/$tdir
14519         kill -USR1 $MULTIPID
14520         wait $MULTIPID
14521         stat $DIR/$tdir && error "open-unlinked dir was not removed!"
14522         return 0
14523 }
14524 run_test 181 "Test open-unlinked dir ========================"
14525
14526 test_182() {
14527         local fcount=1000
14528         local tcount=10
14529
14530         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14531
14532         $LCTL set_param mdc.*.rpc_stats=clear
14533
14534         for (( i = 0; i < $tcount; i++ )) ; do
14535                 mkdir $DIR/$tdir/$i
14536         done
14537
14538         for (( i = 0; i < $tcount; i++ )) ; do
14539                 createmany -o $DIR/$tdir/$i/f- $fcount &
14540         done
14541         wait
14542
14543         for (( i = 0; i < $tcount; i++ )) ; do
14544                 unlinkmany $DIR/$tdir/$i/f- $fcount &
14545         done
14546         wait
14547
14548         $LCTL get_param mdc.*.rpc_stats
14549
14550         rm -rf $DIR/$tdir
14551 }
14552 run_test 182 "Test parallel modify metadata operations ================"
14553
14554 test_183() { # LU-2275
14555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14556         remote_mds_nodsh && skip "remote MDS with nodsh"
14557         [[ $MDS1_VERSION -lt $(version_code 2.3.56) ]] &&
14558                 skip "Need MDS version at least 2.3.56"
14559
14560         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14561         echo aaa > $DIR/$tdir/$tfile
14562
14563 #define OBD_FAIL_MDS_NEGATIVE_POSITIVE  0x148
14564         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x148
14565
14566         ls -l $DIR/$tdir && error "ls succeeded, should have failed"
14567         cat $DIR/$tdir/$tfile && error "cat succeeded, should have failed"
14568
14569         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
14570
14571         # Flush negative dentry cache
14572         touch $DIR/$tdir/$tfile
14573
14574         # We are not checking for any leaked references here, they'll
14575         # become evident next time we do cleanup with module unload.
14576         rm -rf $DIR/$tdir
14577 }
14578 run_test 183 "No crash or request leak in case of strange dispositions ========"
14579
14580 # test suite 184 is for LU-2016, LU-2017
14581 test_184a() {
14582         check_swap_layouts_support
14583
14584         dir0=$DIR/$tdir/$testnum
14585         test_mkdir -p -c1 $dir0
14586         ref1=/etc/passwd
14587         ref2=/etc/group
14588         file1=$dir0/f1
14589         file2=$dir0/f2
14590         $LFS setstripe -c1 $file1
14591         cp $ref1 $file1
14592         $LFS setstripe -c2 $file2
14593         cp $ref2 $file2
14594         gen1=$($LFS getstripe -g $file1)
14595         gen2=$($LFS getstripe -g $file2)
14596
14597         $LFS swap_layouts $file1 $file2 || error "swap of file layout failed"
14598         gen=$($LFS getstripe -g $file1)
14599         [[ $gen1 != $gen ]] ||
14600                 "Layout generation on $file1 does not change"
14601         gen=$($LFS getstripe -g $file2)
14602         [[ $gen2 != $gen ]] ||
14603                 "Layout generation on $file2 does not change"
14604
14605         cmp $ref1 $file2 || error "content compare failed ($ref1 != $file2)"
14606         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
14607
14608         lfsck_verify_pfid $file1 $file2 || error "PFID are not transferred"
14609 }
14610 run_test 184a "Basic layout swap"
14611
14612 test_184b() {
14613         check_swap_layouts_support
14614
14615         dir0=$DIR/$tdir/$testnum
14616         mkdir -p $dir0 || error "creating dir $dir0"
14617         file1=$dir0/f1
14618         file2=$dir0/f2
14619         file3=$dir0/f3
14620         dir1=$dir0/d1
14621         dir2=$dir0/d2
14622         mkdir $dir1 $dir2
14623         $LFS setstripe -c1 $file1
14624         $LFS setstripe -c2 $file2
14625         $LFS setstripe -c1 $file3
14626         chown $RUNAS_ID $file3
14627         gen1=$($LFS getstripe -g $file1)
14628         gen2=$($LFS getstripe -g $file2)
14629
14630         $LFS swap_layouts $dir1 $dir2 &&
14631                 error "swap of directories layouts should fail"
14632         $LFS swap_layouts $dir1 $file1 &&
14633                 error "swap of directory and file layouts should fail"
14634         $RUNAS $LFS swap_layouts $file1 $file2 &&
14635                 error "swap of file we cannot write should fail"
14636         $LFS swap_layouts $file1 $file3 &&
14637                 error "swap of file with different owner should fail"
14638         /bin/true # to clear error code
14639 }
14640 run_test 184b "Forbidden layout swap (will generate errors)"
14641
14642 test_184c() {
14643         local cmpn_arg=$(cmp -n 2>&1 | grep "invalid option")
14644         [ -n "$cmpn_arg" ] && skip_env "cmp does not support -n"
14645         check_swap_layouts_support
14646
14647         local dir0=$DIR/$tdir/$testnum
14648         mkdir -p $dir0 || error "creating dir $dir0"
14649
14650         local ref1=$dir0/ref1
14651         local ref2=$dir0/ref2
14652         local file1=$dir0/file1
14653         local file2=$dir0/file2
14654         # create a file large enough for the concurrent test
14655         dd if=/dev/urandom of=$ref1 bs=1M count=$((RANDOM % 50 + 20))
14656         dd if=/dev/urandom of=$ref2 bs=1M count=$((RANDOM % 50 + 20))
14657         echo "ref file size: ref1($(stat -c %s $ref1))," \
14658              "ref2($(stat -c %s $ref2))"
14659
14660         cp $ref2 $file2
14661         dd if=$ref1 of=$file1 bs=16k &
14662         local DD_PID=$!
14663
14664         # Make sure dd starts to copy file
14665         while [ ! -f $file1 ]; do sleep 0.1; done
14666
14667         $LFS swap_layouts $file1 $file2
14668         local rc=$?
14669         wait $DD_PID
14670         [[ $? == 0 ]] || error "concurrent write on $file1 failed"
14671         [[ $rc == 0 ]] || error "swap of $file1 and $file2 failed"
14672
14673         # how many bytes copied before swapping layout
14674         local copied=$(stat -c %s $file2)
14675         local remaining=$(stat -c %s $ref1)
14676         remaining=$((remaining - copied))
14677         echo "Copied $copied bytes before swapping layout..."
14678
14679         cmp -n $copied $file1 $ref2 | grep differ &&
14680                 error "Content mismatch [0, $copied) of ref2 and file1"
14681         cmp -n $copied $file2 $ref1 ||
14682                 error "Content mismatch [0, $copied) of ref1 and file2"
14683         cmp -i $copied:$copied -n $remaining $file1 $ref1 ||
14684                 error "Content mismatch [$copied, EOF) of ref1 and file1"
14685
14686         # clean up
14687         rm -f $ref1 $ref2 $file1 $file2
14688 }
14689 run_test 184c "Concurrent write and layout swap"
14690
14691 test_184d() {
14692         check_swap_layouts_support
14693         [ -z "$(which getfattr 2>/dev/null)" ] &&
14694                 skip_env "no getfattr command"
14695
14696         local file1=$DIR/$tdir/$tfile-1
14697         local file2=$DIR/$tdir/$tfile-2
14698         local file3=$DIR/$tdir/$tfile-3
14699         local lovea1
14700         local lovea2
14701
14702         mkdir -p $DIR/$tdir
14703         touch $file1 || error "create $file1 failed"
14704         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14705                 error "create $file2 failed"
14706         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14707                 error "create $file3 failed"
14708         lovea1=$(get_layout_param $file1)
14709
14710         $LFS swap_layouts $file2 $file3 ||
14711                 error "swap $file2 $file3 layouts failed"
14712         $LFS swap_layouts $file1 $file2 ||
14713                 error "swap $file1 $file2 layouts failed"
14714
14715         lovea2=$(get_layout_param $file2)
14716         echo "$lovea1"
14717         echo "$lovea2"
14718         [ "$lovea1" == "$lovea2" ] || error "lovea $lovea1 != $lovea2"
14719
14720         lovea1=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14721         [[ -z "$lovea1" ]] || error "$file1 shouldn't have lovea"
14722 }
14723 run_test 184d "allow stripeless layouts swap"
14724
14725 test_184e() {
14726         [[ $MDS1_VERSION -ge $(version_code 2.6.94) ]] ||
14727                 skip "Need MDS version at least 2.6.94"
14728         check_swap_layouts_support
14729         [ -z "$(which getfattr 2>/dev/null)" ] &&
14730                 skip_env "no getfattr command"
14731
14732         local file1=$DIR/$tdir/$tfile-1
14733         local file2=$DIR/$tdir/$tfile-2
14734         local file3=$DIR/$tdir/$tfile-3
14735         local lovea
14736
14737         mkdir -p $DIR/$tdir
14738         touch $file1 || error "create $file1 failed"
14739         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file2 ||
14740                 error "create $file2 failed"
14741         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE $file3 ||
14742                 error "create $file3 failed"
14743
14744         $LFS swap_layouts $file1 $file2 ||
14745                 error "swap $file1 $file2 layouts failed"
14746
14747         lovea=$(getfattr -n trusted.lov $file1 | grep ^trusted)
14748         [[ -z "$lovea" ]] || error "$file1 shouldn't have lovea"
14749
14750         echo 123 > $file1 || error "Should be able to write into $file1"
14751
14752         $LFS swap_layouts $file1 $file3 ||
14753                 error "swap $file1 $file3 layouts failed"
14754
14755         echo 123 > $file1 || error "Should be able to write into $file1"
14756
14757         rm -rf $file1 $file2 $file3
14758 }
14759 run_test 184e "Recreate layout after stripeless layout swaps"
14760
14761 test_184f() {
14762         # Create a file with name longer than sizeof(struct stat) ==
14763         # 144 to see if we can get chars from the file name to appear
14764         # in the returned striping. Note that 'f' == 0x66.
14765         local file=$(for ((i = 0; i < 200; i++)); do echo -n f; done)
14766
14767         mkdir -p $DIR/$tdir
14768         mcreate $DIR/$tdir/$file
14769         if lfs find --stripe-count 0x6666 $DIR/$tdir | grep $file; then
14770                 error "IOC_MDC_GETFILEINFO returned garbage striping"
14771         fi
14772 }
14773 run_test 184f "IOC_MDC_GETFILEINFO for files with long names but no striping"
14774
14775 test_185() { # LU-2441
14776         # LU-3553 - no volatile file support in old servers
14777         [[ $MDS1_VERSION -ge $(version_code 2.3.60) ]] ||
14778                 skip "Need MDS version at least 2.3.60"
14779
14780         mkdir -p $DIR/$tdir || error "creating dir $DIR/$tdir"
14781         touch $DIR/$tdir/spoo
14782         local mtime1=$(stat -c "%Y" $DIR/$tdir)
14783         local fid=$($MULTIOP $DIR/$tdir VFw4096c) ||
14784                 error "cannot create/write a volatile file"
14785         [ "$FILESET" == "" ] &&
14786         $CHECKSTAT -t file $MOUNT/.lustre/fid/$fid 2>/dev/null &&
14787                 error "FID is still valid after close"
14788
14789         multiop_bg_pause $DIR/$tdir vVw4096_c
14790         local multi_pid=$!
14791
14792         local OLD_IFS=$IFS
14793         IFS=":"
14794         local fidv=($fid)
14795         IFS=$OLD_IFS
14796         # assume that the next FID for this client is sequential, since stdout
14797         # is unfortunately eaten by multiop_bg_pause
14798         local n=$((${fidv[1]} + 1))
14799         local next_fid="${fidv[0]}:$(printf "0x%x" $n):${fidv[2]}"
14800         if [ "$FILESET" == "" ]; then
14801                 $CHECKSTAT -t file $MOUNT/.lustre/fid/$next_fid ||
14802                         error "FID is missing before close"
14803         fi
14804         kill -USR1 $multi_pid
14805         # 1 second delay, so if mtime change we will see it
14806         sleep 1
14807         local mtime2=$(stat -c "%Y" $DIR/$tdir)
14808         [[ $mtime1 == $mtime2 ]] || error "mtime has changed"
14809 }
14810 run_test 185 "Volatile file support"
14811
14812 function create_check_volatile() {
14813         local idx=$1
14814         local tgt
14815
14816         $MULTIOP $MOUNT/.lustre/fid V${idx}Fw4096_c >&/tmp/${tfile}.fid &
14817         local PID=$!
14818         sleep 1
14819         local FID=$(cat /tmp/${tfile}.fid)
14820         [ "$FID" == "" ] && error "can't get FID for volatile"
14821         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID || error "can't stat $FID"
14822         tgt=$($LFS getstripe -m $MOUNT/.lustre/fid/$FID)
14823         [ "$tgt" != "$idx" ] && error "wrong MDS $tgt, expected $idx"
14824         kill -USR1 $PID
14825         wait
14826         sleep 1
14827         cancel_lru_locks mdc # flush opencache
14828         $CHECKSTAT -t file $MOUNT/.lustre/fid/$FID && error "can stat $FID"
14829         return 0
14830 }
14831
14832 test_185a(){
14833         # LU-12516 - volatile creation via .lustre
14834         [[ $MDS1_VERSION -ge $(version_code 2.12.55) ]] ||
14835                 skip "Need MDS version at least 2.3.55"
14836
14837         create_check_volatile 0
14838         [ $MDSCOUNT -lt 2 ] && return 0
14839
14840         # DNE case
14841         create_check_volatile 1
14842
14843         return 0
14844 }
14845 run_test 185a "Volatile file creation in .lustre/fid/"
14846
14847 test_187a() {
14848         remote_mds_nodsh && skip "remote MDS with nodsh"
14849         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14850                 skip "Need MDS version at least 2.3.0"
14851
14852         local dir0=$DIR/$tdir/$testnum
14853         mkdir -p $dir0 || error "creating dir $dir0"
14854
14855         local file=$dir0/file1
14856         dd if=/dev/urandom of=$file count=10 bs=1M conv=fsync
14857         local dv1=$($LFS data_version $file)
14858         dd if=/dev/urandom of=$file seek=10 count=1 bs=1M conv=fsync
14859         local dv2=$($LFS data_version $file)
14860         [[ $dv1 != $dv2 ]] ||
14861                 error "data version did not change on write $dv1 == $dv2"
14862
14863         # clean up
14864         rm -f $file1
14865 }
14866 run_test 187a "Test data version change"
14867
14868 test_187b() {
14869         remote_mds_nodsh && skip "remote MDS with nodsh"
14870         [ $MDS1_VERSION -lt $(version_code 2.3.0) ] &&
14871                 skip "Need MDS version at least 2.3.0"
14872
14873         local dir0=$DIR/$tdir/$testnum
14874         mkdir -p $dir0 || error "creating dir $dir0"
14875
14876         declare -a DV=$($MULTIOP $dir0 Vw1000xYw1000xY | cut -f3 -d" ")
14877         [[ ${DV[0]} != ${DV[1]} ]] ||
14878                 error "data version did not change on write"\
14879                       " ${DV[0]} == ${DV[1]}"
14880
14881         # clean up
14882         rm -f $file1
14883 }
14884 run_test 187b "Test data version change on volatile file"
14885
14886 test_200() {
14887         [ $PARALLEL == "yes" ] && skip "skip parallel run"
14888         remote_mgs_nodsh && skip "remote MGS with nodsh"
14889         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
14890
14891         local POOL=${POOL:-cea1}
14892         local POOL_ROOT=${POOL_ROOT:-$DIR/d200.pools}
14893         local POOL_DIR_NAME=${POOL_DIR_NAME:-dir_tst}
14894         # Pool OST targets
14895         local first_ost=0
14896         local last_ost=$(($OSTCOUNT - 1))
14897         local ost_step=2
14898         local ost_list=$(seq $first_ost $ost_step $last_ost)
14899         local ost_range="$first_ost $last_ost $ost_step"
14900         local test_path=$POOL_ROOT/$POOL_DIR_NAME
14901         local file_dir=$POOL_ROOT/file_tst
14902         local subdir=$test_path/subdir
14903         local rc=0
14904
14905         if ! combined_mgs_mds ; then
14906                 mount_mgs_client
14907         fi
14908
14909         while : ; do
14910                 # former test_200a test_200b
14911                 pool_add $POOL                          || { rc=$? ; break; }
14912                 pool_add_targets  $POOL $ost_range      || { rc=$? ; break; }
14913                 # former test_200c test_200d
14914                 mkdir -p $test_path
14915                 pool_set_dir      $POOL $test_path      || { rc=$? ; break; }
14916                 pool_check_dir    $POOL $test_path      || { rc=$? ; break; }
14917                 mkdir -p $subdir
14918                 pool_check_dir    $POOL $subdir         || { rc=$? ; break; }
14919                 pool_dir_rel_path $POOL $POOL_DIR_NAME $POOL_ROOT \
14920                                                         || { rc=$? ; break; }
14921                 # former test_200e test_200f
14922                 local files=$((OSTCOUNT*3))
14923                 pool_alloc_files  $POOL $test_path $files "$ost_list" \
14924                                                         || { rc=$? ; break; }
14925                 pool_create_files $POOL $file_dir $files "$ost_list" \
14926                                                         || { rc=$? ; break; }
14927                 # former test_200g test_200h
14928                 pool_lfs_df $POOL                       || { rc=$? ; break; }
14929                 pool_file_rel_path $POOL $test_path     || { rc=$? ; break; }
14930
14931                 # former test_201a test_201b test_201c
14932                 pool_remove_first_target $POOL          || { rc=$? ; break; }
14933
14934                 local f=$test_path/$tfile
14935                 pool_remove_all_targets $POOL $f        || { rc=$? ; break; }
14936                 pool_remove $POOL $f                    || { rc=$? ; break; }
14937                 break
14938         done
14939
14940         destroy_test_pools
14941
14942         if ! combined_mgs_mds ; then
14943                 umount_mgs_client
14944         fi
14945         return $rc
14946 }
14947 run_test 200 "OST pools"
14948
14949 # usage: default_attr <count | size | offset>
14950 default_attr() {
14951         $LCTL get_param -n lov.$FSNAME-clilov-\*.stripe${1}
14952 }
14953
14954 # usage: check_default_stripe_attr
14955 check_default_stripe_attr() {
14956         ACTUAL=$($LFS getstripe $* $DIR/$tdir)
14957         case $1 in
14958         --stripe-count|-c)
14959                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr count);;
14960         --stripe-size|-S)
14961                 [ -n "$2" ] && EXPECTED=0 || EXPECTED=$(default_attr size);;
14962         --stripe-index|-i)
14963                 EXPECTED=-1;;
14964         *)
14965                 error "unknown getstripe attr '$1'"
14966         esac
14967
14968         [ $ACTUAL == $EXPECTED ] ||
14969                 error "$DIR/$tdir has $1 '$ACTUAL', not '$EXPECTED'"
14970 }
14971
14972 test_204a() {
14973         test_mkdir $DIR/$tdir
14974         $LFS setstripe --stripe-count 0 --stripe-size 0 --stripe-index -1 $DIR/$tdir
14975
14976         check_default_stripe_attr --stripe-count
14977         check_default_stripe_attr --stripe-size
14978         check_default_stripe_attr --stripe-index
14979 }
14980 run_test 204a "Print default stripe attributes"
14981
14982 test_204b() {
14983         test_mkdir $DIR/$tdir
14984         $LFS setstripe --stripe-count 1 $DIR/$tdir
14985
14986         check_default_stripe_attr --stripe-size
14987         check_default_stripe_attr --stripe-index
14988 }
14989 run_test 204b "Print default stripe size and offset"
14990
14991 test_204c() {
14992         test_mkdir $DIR/$tdir
14993         $LFS setstripe --stripe-size 65536 $DIR/$tdir
14994
14995         check_default_stripe_attr --stripe-count
14996         check_default_stripe_attr --stripe-index
14997 }
14998 run_test 204c "Print default stripe count and offset"
14999
15000 test_204d() {
15001         test_mkdir $DIR/$tdir
15002         $LFS setstripe --stripe-index 0 $DIR/$tdir
15003
15004         check_default_stripe_attr --stripe-count
15005         check_default_stripe_attr --stripe-size
15006 }
15007 run_test 204d "Print default stripe count and size"
15008
15009 test_204e() {
15010         test_mkdir $DIR/$tdir
15011         $LFS setstripe -d $DIR/$tdir
15012
15013         check_default_stripe_attr --stripe-count --raw
15014         check_default_stripe_attr --stripe-size --raw
15015         check_default_stripe_attr --stripe-index --raw
15016 }
15017 run_test 204e "Print raw stripe attributes"
15018
15019 test_204f() {
15020         test_mkdir $DIR/$tdir
15021         $LFS setstripe --stripe-count 1 $DIR/$tdir
15022
15023         check_default_stripe_attr --stripe-size --raw
15024         check_default_stripe_attr --stripe-index --raw
15025 }
15026 run_test 204f "Print raw stripe size and offset"
15027
15028 test_204g() {
15029         test_mkdir $DIR/$tdir
15030         $LFS setstripe --stripe-size 65536 $DIR/$tdir
15031
15032         check_default_stripe_attr --stripe-count --raw
15033         check_default_stripe_attr --stripe-index --raw
15034 }
15035 run_test 204g "Print raw stripe count and offset"
15036
15037 test_204h() {
15038         test_mkdir $DIR/$tdir
15039         $LFS setstripe --stripe-index 0 $DIR/$tdir
15040
15041         check_default_stripe_attr --stripe-count --raw
15042         check_default_stripe_attr --stripe-size --raw
15043 }
15044 run_test 204h "Print raw stripe count and size"
15045
15046 # Figure out which job scheduler is being used, if any,
15047 # or use a fake one
15048 if [ -n "$SLURM_JOB_ID" ]; then # SLURM
15049         JOBENV=SLURM_JOB_ID
15050 elif [ -n "$LSB_JOBID" ]; then # Load Sharing Facility
15051         JOBENV=LSB_JOBID
15052 elif [ -n "$PBS_JOBID" ]; then # PBS/Maui/Moab
15053         JOBENV=PBS_JOBID
15054 elif [ -n "$LOADL_STEPID" ]; then # LoadLeveller
15055         JOBENV=LOADL_STEP_ID
15056 elif [ -n "$JOB_ID" ]; then # Sun Grid Engine
15057         JOBENV=JOB_ID
15058 else
15059         $LCTL list_param jobid_name > /dev/null 2>&1
15060         if [ $? -eq 0 ]; then
15061                 JOBENV=nodelocal
15062         else
15063                 JOBENV=FAKE_JOBID
15064         fi
15065 fi
15066 LUSTRE_JOBID_SIZE=31 # plus NUL terminator
15067
15068 verify_jobstats() {
15069         local cmd=($1)
15070         shift
15071         local facets="$@"
15072
15073 # we don't really need to clear the stats for this test to work, since each
15074 # command has a unique jobid, but it makes debugging easier if needed.
15075 #       for facet in $facets; do
15076 #               local dev=$(convert_facet2label $facet)
15077 #               # clear old jobstats
15078 #               do_facet $facet lctl set_param *.$dev.job_stats="clear"
15079 #       done
15080
15081         # use a new JobID for each test, or we might see an old one
15082         [ "$JOBENV" = "FAKE_JOBID" ] &&
15083                 FAKE_JOBID=id.$testnum.$(basename ${cmd[0]}).$RANDOM
15084
15085         JOBVAL=${!JOBENV:0:$LUSTRE_JOBID_SIZE}
15086
15087         [ "$JOBENV" = "nodelocal" ] && {
15088                 FAKE_JOBID=id.$testnum.%e.$RANDOM
15089                 $LCTL set_param jobid_name=$FAKE_JOBID
15090                 JOBVAL=${FAKE_JOBID/\%e/$(basename ${cmd[0]})}
15091         }
15092
15093         log "Test: ${cmd[*]}"
15094         log "Using JobID environment $($LCTL get_param -n jobid_var)=$JOBVAL"
15095
15096         if [ $JOBENV = "FAKE_JOBID" ]; then
15097                 FAKE_JOBID=$JOBVAL ${cmd[*]}
15098         else
15099                 ${cmd[*]}
15100         fi
15101
15102         # all files are created on OST0000
15103         for facet in $facets; do
15104                 local stats="*.$(convert_facet2label $facet).job_stats"
15105
15106                 # strip out libtool wrappers for in-tree executables
15107                 if [ $(do_facet $facet lctl get_param $stats |
15108                        sed -e 's/\.lt-/./' | grep -c $JOBVAL) -ne 1 ]; then
15109                         do_facet $facet lctl get_param $stats
15110                         error "No jobstats for $JOBVAL found on $facet::$stats"
15111                 fi
15112         done
15113 }
15114
15115 jobstats_set() {
15116         local new_jobenv=$1
15117
15118         set_persistent_param_and_check client "jobid_var" \
15119                 "$FSNAME.sys.jobid_var" $new_jobenv
15120 }
15121
15122 test_205() { # Job stats
15123         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15124         [[ $MDS1_VERSION -ge $(version_code 2.7.1) ]] ||
15125                 skip "Need MDS version with at least 2.7.1"
15126         remote_mgs_nodsh && skip "remote MGS with nodsh"
15127         remote_mds_nodsh && skip "remote MDS with nodsh"
15128         remote_ost_nodsh && skip "remote OST with nodsh"
15129         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep jobstats)" ] &&
15130                 skip "Server doesn't support jobstats"
15131         [[ $JOBID_VAR = disable ]] && skip_env "jobstats is disabled"
15132
15133         local old_jobenv=$($LCTL get_param -n jobid_var)
15134         [ $old_jobenv != $JOBENV ] && jobstats_set $JOBENV
15135
15136         if [[ $PERM_CMD == *"set_param -P"* ]]; then
15137                 stack_trap "do_facet mgs $PERM_CMD jobid_var=$old_jobenv" EXIT
15138         else
15139                 stack_trap "do_facet mgs $PERM_CMD \
15140                         $FSNAME.sys.jobid_var=$old_jobenv" EXIT
15141         fi
15142         changelog_register
15143
15144         local old_interval=$(do_facet $SINGLEMDS lctl get_param -n \
15145                                 mdt.*.job_cleanup_interval | head -n 1)
15146         local new_interval=5
15147         do_facet $SINGLEMDS \
15148                 $LCTL set_param mdt.*.job_cleanup_interval=$new_interval
15149         stack_trap "do_facet $SINGLEMDS \
15150                 $LCTL set_param mdt.*.job_cleanup_interval=$old_interval" EXIT
15151         local start=$SECONDS
15152
15153         local cmd
15154         # mkdir
15155         cmd="mkdir $DIR/$tdir"
15156         verify_jobstats "$cmd" "$SINGLEMDS"
15157         # rmdir
15158         cmd="rmdir $DIR/$tdir"
15159         verify_jobstats "$cmd" "$SINGLEMDS"
15160         # mkdir on secondary MDT
15161         if [ $MDSCOUNT -gt 1 ]; then
15162                 cmd="lfs mkdir -i 1 $DIR/$tdir.remote"
15163                 verify_jobstats "$cmd" "mds2"
15164         fi
15165         # mknod
15166         cmd="mknod $DIR/$tfile c 1 3"
15167         verify_jobstats "$cmd" "$SINGLEMDS"
15168         # unlink
15169         cmd="rm -f $DIR/$tfile"
15170         verify_jobstats "$cmd" "$SINGLEMDS"
15171         # create all files on OST0000 so verify_jobstats can find OST stats
15172         # open & close
15173         cmd="$LFS setstripe -i 0 -c 1 $DIR/$tfile"
15174         verify_jobstats "$cmd" "$SINGLEMDS"
15175         # setattr
15176         cmd="touch $DIR/$tfile"
15177         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15178         # write
15179         cmd="dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 oflag=sync"
15180         verify_jobstats "$cmd" "ost1"
15181         # read
15182         cancel_lru_locks osc
15183         cmd="dd if=$DIR/$tfile of=/dev/null bs=1M count=1 iflag=direct"
15184         verify_jobstats "$cmd" "ost1"
15185         # truncate
15186         cmd="$TRUNCATE $DIR/$tfile 0"
15187         verify_jobstats "$cmd" "$SINGLEMDS ost1"
15188         # rename
15189         cmd="mv -f $DIR/$tfile $DIR/$tdir.rename"
15190         verify_jobstats "$cmd" "$SINGLEMDS"
15191         # jobstats expiry - sleep until old stats should be expired
15192         local left=$((new_interval + 5 - (SECONDS - start)))
15193         [ $left -ge 0 ] && wait_update_facet $SINGLEMDS \
15194                 "lctl get_param *.*.job_stats | grep -c 'job_id.*mkdir'" \
15195                         "0" $left
15196         cmd="mkdir $DIR/$tdir.expire"
15197         verify_jobstats "$cmd" "$SINGLEMDS"
15198         [ $(do_facet $SINGLEMDS lctl get_param *.*.job_stats |
15199             grep -c "job_id.*mkdir") -gt 1 ] && error "old jobstats not expired"
15200
15201         # Ensure that jobid are present in changelog (if supported by MDS)
15202         if [ $MDS1_VERSION -ge $(version_code 2.6.52) ];then
15203                 changelog_dump | tail -10
15204                 jobids=$(changelog_dump | tail -9 | grep -c "j=")
15205                 [ $jobids -eq 9 ] ||
15206                         error "Wrong changelog jobid count $jobids != 9"
15207
15208                 # LU-5862
15209                 JOBENV="disable"
15210                 jobstats_set $JOBENV
15211                 touch $DIR/$tfile
15212                 changelog_dump | grep $tfile
15213                 jobids=$(changelog_dump | grep $tfile | tail -1 | grep -c "j=")
15214                 [ $jobids -eq 0 ] ||
15215                         error "Unexpected jobids when jobid_var=$JOBENV"
15216         fi
15217
15218         lctl set_param jobid_var=USER jobid_name="S.%j.%e.%u.%h.E"
15219         JOBENV="JOBCOMPLEX"
15220         JOBCOMPLEX="S.$USER.touch.$(id -u).$(hostname).E"
15221
15222         verify_jobstats "touch $DIR/$tfile" $SINGLEMDS
15223 }
15224 run_test 205 "Verify job stats"
15225
15226 # LU-1480, LU-1773 and LU-1657
15227 test_206() {
15228         mkdir -p $DIR/$tdir
15229         $LFS setstripe -c -1 $DIR/$tdir
15230 #define OBD_FAIL_LOV_INIT 0x1403
15231         $LCTL set_param fail_loc=0xa0001403
15232         $LCTL set_param fail_val=1
15233         touch $DIR/$tdir/$tfile || true
15234 }
15235 run_test 206 "fail lov_init_raid0() doesn't lbug"
15236
15237 test_207a() {
15238         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15239         local fsz=`stat -c %s $DIR/$tfile`
15240         cancel_lru_locks mdc
15241
15242         # do not return layout in getattr intent
15243 #define OBD_FAIL_MDS_NO_LL_GETATTR 0x170
15244         $LCTL set_param fail_loc=0x170
15245         local sz=`stat -c %s $DIR/$tfile`
15246
15247         [ $fsz -eq $sz ] || error "file size expected $fsz, actual $sz"
15248
15249         rm -rf $DIR/$tfile
15250 }
15251 run_test 207a "can refresh layout at glimpse"
15252
15253 test_207b() {
15254         dd if=/dev/zero of=$DIR/$tfile bs=4k count=$((RANDOM%10+1))
15255         local cksum=`md5sum $DIR/$tfile`
15256         local fsz=`stat -c %s $DIR/$tfile`
15257         cancel_lru_locks mdc
15258         cancel_lru_locks osc
15259
15260         # do not return layout in getattr intent
15261 #define OBD_FAIL_MDS_NO_LL_OPEN 0x171
15262         $LCTL set_param fail_loc=0x171
15263
15264         # it will refresh layout after the file is opened but before read issues
15265         echo checksum is "$cksum"
15266         echo "$cksum" |md5sum -c --quiet || error "file differs"
15267
15268         rm -rf $DIR/$tfile
15269 }
15270 run_test 207b "can refresh layout at open"
15271
15272 test_208() {
15273         # FIXME: in this test suite, only RD lease is used. This is okay
15274         # for now as only exclusive open is supported. After generic lease
15275         # is done, this test suite should be revised. - Jinshan
15276
15277         remote_mds_nodsh && skip "remote MDS with nodsh"
15278         [[ $MDS1_VERSION -ge $(version_code 2.4.52) ]] ||
15279                 skip "Need MDS version at least 2.4.52"
15280
15281         echo "==== test 1: verify get lease work"
15282         $MULTIOP $DIR/$tfile oO_CREAT:O_RDWR:eRE+eU || error "get lease error"
15283
15284         echo "==== test 2: verify lease can be broken by upcoming open"
15285         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15286         local PID=$!
15287         sleep 1
15288
15289         $MULTIOP $DIR/$tfile oO_RDONLY:c
15290         kill -USR1 $PID && wait $PID || error "break lease error"
15291
15292         echo "==== test 3: verify lease can't be granted if an open already exists"
15293         $MULTIOP $DIR/$tfile oO_RDONLY:_c &
15294         local PID=$!
15295         sleep 1
15296
15297         $MULTIOP $DIR/$tfile oO_RDONLY:eReUc && error "apply lease should fail"
15298         kill -USR1 $PID && wait $PID || error "open file error"
15299
15300         echo "==== test 4: lease can sustain over recovery"
15301         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E+eUc &
15302         PID=$!
15303         sleep 1
15304
15305         fail mds1
15306
15307         kill -USR1 $PID && wait $PID || error "lease broken over recovery"
15308
15309         echo "==== test 5: lease broken can't be regained by replay"
15310         $MULTIOP $DIR/$tfile oO_RDONLY:eR_E-eUc &
15311         PID=$!
15312         sleep 1
15313
15314         # open file to break lease and then recovery
15315         $MULTIOP $DIR/$tfile oO_RDWR:c || error "open file error"
15316         fail mds1
15317
15318         kill -USR1 $PID && wait $PID || error "lease not broken over recovery"
15319
15320         rm -f $DIR/$tfile
15321 }
15322 run_test 208 "Exclusive open"
15323
15324 test_209() {
15325         [ -z "$(lctl get_param -n mdc.*.connect_flags | grep disp_stripe)" ] &&
15326                 skip_env "must have disp_stripe"
15327
15328         touch $DIR/$tfile
15329         sync; sleep 5; sync;
15330
15331         echo 3 > /proc/sys/vm/drop_caches
15332         req_before=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15333
15334         # open/close 500 times
15335         for i in $(seq 500); do
15336                 cat $DIR/$tfile
15337         done
15338
15339         echo 3 > /proc/sys/vm/drop_caches
15340         req_after=$(awk '/ptlrpc_cache / { print $2 }' /proc/slabinfo)
15341
15342         echo "before: $req_before, after: $req_after"
15343         [ $((req_after - req_before)) -ge 300 ] &&
15344                 error "open/close requests are not freed"
15345         return 0
15346 }
15347 run_test 209 "read-only open/close requests should be freed promptly"
15348
15349 test_212() {
15350         size=`date +%s`
15351         size=$((size % 8192 + 1))
15352         dd if=/dev/urandom of=$DIR/f212 bs=1k count=$size
15353         sendfile $DIR/f212 $DIR/f212.xyz || error "sendfile wrong"
15354         rm -f $DIR/f212 $DIR/f212.xyz
15355 }
15356 run_test 212 "Sendfile test ============================================"
15357
15358 test_213() {
15359         dd if=/dev/zero of=$DIR/$tfile bs=4k count=4
15360         cancel_lru_locks osc
15361         lctl set_param fail_loc=0x8000040f
15362         # generate a read lock
15363         cat $DIR/$tfile > /dev/null
15364         # write to the file, it will try to cancel the above read lock.
15365         cat /etc/hosts >> $DIR/$tfile
15366 }
15367 run_test 213 "OSC lock completion and cancel race don't crash - bug 18829"
15368
15369 test_214() { # for bug 20133
15370         mkdir -p $DIR/$tdir/d214c || error "mkdir $DIR/$tdir/d214c failed"
15371         for (( i=0; i < 340; i++ )) ; do
15372                 touch $DIR/$tdir/d214c/a$i
15373         done
15374
15375         ls -l $DIR/$tdir || error "ls -l $DIR/d214p failed"
15376         mv $DIR/$tdir/d214c $DIR/ || error "mv $DIR/d214p/d214c $DIR/ failed"
15377         ls $DIR/d214c || error "ls $DIR/d214c failed"
15378         rm -rf $DIR/$tdir || error "rm -rf $DIR/d214* failed"
15379         rm -rf $DIR/d214* || error "rm -rf $DIR/d214* failed"
15380 }
15381 run_test 214 "hash-indexed directory test - bug 20133"
15382
15383 # having "abc" as 1st arg, creates $TMP/lnet_abc.out and $TMP/lnet_abc.sys
15384 create_lnet_proc_files() {
15385         lctl get_param -n $1 >$TMP/lnet_$1.sys || error "cannot read lnet.$1"
15386 }
15387
15388 # counterpart of create_lnet_proc_files
15389 remove_lnet_proc_files() {
15390         rm -f $TMP/lnet_$1.sys
15391 }
15392
15393 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15394 # 3rd arg as regexp for body
15395 check_lnet_proc_stats() {
15396         local l=$(cat "$TMP/lnet_$1" |wc -l)
15397         [ $l = 1 ] || (cat "$TMP/lnet_$1" && error "$2 is not of 1 line: $l")
15398
15399         grep -E "$3" "$TMP/lnet_$1" || (cat "$TMP/lnet_$1" && error "$2 misformatted")
15400 }
15401
15402 # uses 1st arg as trailing part of filename, 2nd arg as description for reports,
15403 # 3rd arg as regexp for body, 4th arg as regexp for 1st line, 5th arg is
15404 # optional and can be regexp for 2nd line (lnet.routes case)
15405 check_lnet_proc_entry() {
15406         local blp=2          # blp stands for 'position of 1st line of body'
15407         [ -z "$5" ] || blp=3 # lnet.routes case
15408
15409         local l=$(cat "$TMP/lnet_$1" |wc -l)
15410         # subtracting one from $blp because the body can be empty
15411         [ "$l" -ge "$(($blp - 1))" ] || (cat "$TMP/lnet_$1" && error "$2 is too short: $l")
15412
15413         sed -n '1 p' "$TMP/lnet_$1" |grep -E "$4" >/dev/null ||
15414                 (cat "$TMP/lnet_$1" && error "1st line of $2 misformatted")
15415
15416         [ "$5" = "" ] || sed -n '2 p' "$TMP/lnet_$1" |grep -E "$5" >/dev/null ||
15417                 (cat "$TMP/lnet_$1" && error "2nd line of $2 misformatted")
15418
15419         # bail out if any unexpected line happened
15420         sed -n "$blp p" "$TMP/lnet_$1" | grep -Ev "$3"
15421         [ "$?" != 0 ] || error "$2 misformatted"
15422 }
15423
15424 test_215() { # for bugs 18102, 21079, 21517
15425         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15426
15427         local N='(0|[1-9][0-9]*)'       # non-negative numeric
15428         local P='[1-9][0-9]*'           # positive numeric
15429         local I='(0|-?[1-9][0-9]*|NA)'  # any numeric (0 | >0 | <0) or NA if no value
15430         local NET='[a-z][a-z0-9]*'      # LNET net like o2ib2
15431         local ADDR='[0-9.]+'            # LNET addr like 10.0.0.1
15432         local NID="$ADDR@$NET"          # LNET nid like 10.0.0.1@o2ib2
15433
15434         local L1 # regexp for 1st line
15435         local L2 # regexp for 2nd line (optional)
15436         local BR # regexp for the rest (body)
15437
15438         # lnet.stats should look as 11 space-separated non-negative numerics
15439         BR="^$N $N $N $N $N $N $N $N $N $N $N$"
15440         create_lnet_proc_files "stats"
15441         check_lnet_proc_stats "stats.sys" "lnet.stats" "$BR"
15442         remove_lnet_proc_files "stats"
15443
15444         # lnet.routes should look like this:
15445         # Routing disabled/enabled
15446         # net hops priority state router
15447         # where net is a string like tcp0, hops > 0, priority >= 0,
15448         # state is up/down,
15449         # router is a string like 192.168.1.1@tcp2
15450         L1="^Routing (disabled|enabled)$"
15451         L2="^net +hops +priority +state +router$"
15452         BR="^$NET +$N +(0|1) +(up|down) +$NID$"
15453         create_lnet_proc_files "routes"
15454         check_lnet_proc_entry "routes.sys" "lnet.routes" "$BR" "$L1" "$L2"
15455         remove_lnet_proc_files "routes"
15456
15457         # lnet.routers should look like this:
15458         # ref rtr_ref alive_cnt state last_ping ping_sent deadline down_ni router
15459         # where ref > 0, rtr_ref > 0, alive_cnt >= 0, state is up/down,
15460         # last_ping >= 0, ping_sent is boolean (0/1), deadline and down_ni are
15461         # numeric (0 or >0 or <0), router is a string like 192.168.1.1@tcp2
15462         L1="^ref +rtr_ref +alive +router$"
15463         BR="^$P +$P +(up|down) +$NID$"
15464         create_lnet_proc_files "routers"
15465         check_lnet_proc_entry "routers.sys" "lnet.routers" "$BR" "$L1"
15466         remove_lnet_proc_files "routers"
15467
15468         # lnet.peers should look like this:
15469         # nid refs state last max rtr min tx min queue
15470         # where nid is a string like 192.168.1.1@tcp2, refs > 0,
15471         # state is up/down/NA, max >= 0. last, rtr, min, tx, min are
15472         # numeric (0 or >0 or <0), queue >= 0.
15473         L1="^nid +refs +state +last +max +rtr +min +tx +min +queue$"
15474         BR="^$NID +$P +(up|down|NA) +$I +$N +$I +$I +$I +$I +$N$"
15475         create_lnet_proc_files "peers"
15476         check_lnet_proc_entry "peers.sys" "lnet.peers" "$BR" "$L1"
15477         remove_lnet_proc_files "peers"
15478
15479         # lnet.buffers  should look like this:
15480         # pages count credits min
15481         # where pages >=0, count >=0, credits and min are numeric (0 or >0 or <0)
15482         L1="^pages +count +credits +min$"
15483         BR="^ +$N +$N +$I +$I$"
15484         create_lnet_proc_files "buffers"
15485         check_lnet_proc_entry "buffers.sys" "lnet.buffers" "$BR" "$L1"
15486         remove_lnet_proc_files "buffers"
15487
15488         # lnet.nis should look like this:
15489         # nid status alive refs peer rtr max tx min
15490         # where nid is a string like 192.168.1.1@tcp2, status is up/down,
15491         # alive is numeric (0 or >0 or <0), refs >= 0, peer >= 0,
15492         # rtr >= 0, max >=0, tx and min are numeric (0 or >0 or <0).
15493         L1="^nid +status +alive +refs +peer +rtr +max +tx +min$"
15494         BR="^$NID +(up|down) +$I +$N +$N +$N +$N +$I +$I$"
15495         create_lnet_proc_files "nis"
15496         check_lnet_proc_entry "nis.sys" "lnet.nis" "$BR" "$L1"
15497         remove_lnet_proc_files "nis"
15498
15499         # can we successfully write to lnet.stats?
15500         lctl set_param -n stats=0 || error "cannot write to lnet.stats"
15501 }
15502 run_test 215 "lnet exists and has proper content - bugs 18102, 21079, 21517"
15503
15504 test_216() { # bug 20317
15505         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15506         remote_ost_nodsh && skip "remote OST with nodsh"
15507
15508         local node
15509         local facets=$(get_facets OST)
15510         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15511
15512         save_lustre_params client "osc.*.contention_seconds" > $p
15513         save_lustre_params $facets \
15514                 "ldlm.namespaces.filter-*.max_nolock_bytes" >> $p
15515         save_lustre_params $facets \
15516                 "ldlm.namespaces.filter-*.contended_locks" >> $p
15517         save_lustre_params $facets \
15518                 "ldlm.namespaces.filter-*.contention_seconds" >> $p
15519         clear_stats osc.*.osc_stats
15520
15521         # agressive lockless i/o settings
15522         do_nodes $(comma_list $(osts_nodes)) \
15523                 "lctl set_param -n ldlm.namespaces.*.max_nolock_bytes=2000000 \
15524                         ldlm.namespaces.filter-*.contended_locks=0 \
15525                         ldlm.namespaces.filter-*.contention_seconds=60"
15526         lctl set_param -n osc.*.contention_seconds=60
15527
15528         $DIRECTIO write $DIR/$tfile 0 10 4096
15529         $CHECKSTAT -s 40960 $DIR/$tfile
15530
15531         # disable lockless i/o
15532         do_nodes $(comma_list $(osts_nodes)) \
15533                 "lctl set_param -n ldlm.namespaces.filter-*.max_nolock_bytes=0 \
15534                         ldlm.namespaces.filter-*.contended_locks=32 \
15535                         ldlm.namespaces.filter-*.contention_seconds=0"
15536         lctl set_param -n osc.*.contention_seconds=0
15537         clear_stats osc.*.osc_stats
15538
15539         dd if=/dev/zero of=$DIR/$tfile count=0
15540         $CHECKSTAT -s 0 $DIR/$tfile
15541
15542         restore_lustre_params <$p
15543         rm -f $p
15544         rm $DIR/$tfile
15545 }
15546 run_test 216 "check lockless direct write updates file size and kms correctly"
15547
15548 test_217() { # bug 22430
15549         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15550
15551         local node
15552         local nid
15553
15554         for node in $(nodes_list); do
15555                 nid=$(host_nids_address $node $NETTYPE)
15556                 if [[ $nid = *-* ]] ; then
15557                         echo "lctl ping $(h2nettype $nid)"
15558                         lctl ping $(h2nettype $nid)
15559                 else
15560                         echo "skipping $node (no hyphen detected)"
15561                 fi
15562         done
15563 }
15564 run_test 217 "check lctl ping for hostnames with hiphen ('-')"
15565
15566 test_218() {
15567        # do directio so as not to populate the page cache
15568        log "creating a 10 Mb file"
15569        $MULTIOP $DIR/$tfile oO_CREAT:O_DIRECT:O_RDWR:w$((10*1048576))c || error "multiop failed while creating a file"
15570        log "starting reads"
15571        dd if=$DIR/$tfile of=/dev/null bs=4096 &
15572        log "truncating the file"
15573        $MULTIOP $DIR/$tfile oO_TRUNC:c || error "multiop failed while truncating the file"
15574        log "killing dd"
15575        kill %+ || true # reads might have finished
15576        echo "wait until dd is finished"
15577        wait
15578        log "removing the temporary file"
15579        rm -rf $DIR/$tfile || error "tmp file removal failed"
15580 }
15581 run_test 218 "parallel read and truncate should not deadlock"
15582
15583 test_219() {
15584         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15585
15586         # write one partial page
15587         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1
15588         # set no grant so vvp_io_commit_write will do sync write
15589         $LCTL set_param fail_loc=0x411
15590         # write a full page at the end of file
15591         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=1 conv=notrunc
15592
15593         $LCTL set_param fail_loc=0
15594         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 seek=3
15595         $LCTL set_param fail_loc=0x411
15596         dd if=/dev/zero of=$DIR/$tfile bs=1024 count=1 seek=2 conv=notrunc
15597
15598         # LU-4201
15599         dd if=/dev/zero of=$DIR/$tfile-2 bs=1024 count=1
15600         $CHECKSTAT -s 1024 $DIR/$tfile-2 || error "checkstat wrong size"
15601 }
15602 run_test 219 "LU-394: Write partial won't cause uncontiguous pages vec at LND"
15603
15604 test_220() { #LU-325
15605         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15606         remote_ost_nodsh && skip "remote OST with nodsh"
15607         remote_mds_nodsh && skip "remote MDS with nodsh"
15608         remote_mgs_nodsh && skip "remote MGS with nodsh"
15609
15610         local OSTIDX=0
15611
15612         # create on MDT0000 so the last_id and next_id are correct
15613         mkdir $DIR/$tdir
15614         local OST=$($LFS df $DIR | awk '/OST:'$OSTIDX'/ { print $1 }')
15615         OST=${OST%_UUID}
15616
15617         # on the mdt's osc
15618         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $OST)
15619         local last_id=$(do_facet $SINGLEMDS lctl get_param -n \
15620                         osp.$mdtosc_proc1.prealloc_last_id)
15621         local next_id=$(do_facet $SINGLEMDS lctl get_param -n \
15622                         osp.$mdtosc_proc1.prealloc_next_id)
15623
15624         $LFS df -i
15625
15626         if ! combined_mgs_mds ; then
15627                 mount_mgs_client
15628         fi
15629
15630         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=-1
15631         #define OBD_FAIL_OST_ENOINO              0x229
15632         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0x229
15633         create_pool $FSNAME.$TESTNAME || return 1
15634         do_facet mgs $LCTL pool_add $FSNAME.$TESTNAME $OST || return 2
15635
15636         $LFS setstripe $DIR/$tdir -i $OSTIDX -c 1 -p $FSNAME.$TESTNAME
15637
15638         MDSOBJS=$((last_id - next_id))
15639         echo "preallocated objects on MDS is $MDSOBJS" "($last_id - $next_id)"
15640
15641         blocks=$($LFS df $MOUNT | awk '($1 == '$OSTIDX') { print $4 }')
15642         echo "OST still has $count kbytes free"
15643
15644         echo "create $MDSOBJS files @next_id..."
15645         createmany -o $DIR/$tdir/f $MDSOBJS || return 3
15646
15647         local last_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15648                         osp.$mdtosc_proc1.prealloc_last_id)
15649         local next_id2=$(do_facet mds${MDSIDX} lctl get_param -n \
15650                         osp.$mdtosc_proc1.prealloc_next_id)
15651
15652         echo "after creation, last_id=$last_id2, next_id=$next_id2"
15653         $LFS df -i
15654
15655         echo "cleanup..."
15656
15657         do_facet ost$((OSTIDX + 1)) lctl set_param fail_val=0
15658         do_facet ost$((OSTIDX + 1)) lctl set_param fail_loc=0
15659
15660         do_facet mgs $LCTL pool_remove $FSNAME.$TESTNAME $OST ||
15661                 error "$LCTL pool_remove $FSNAME.$TESTNAME $OST failed"
15662         do_facet mgs $LCTL pool_destroy $FSNAME.$TESTNAME ||
15663                 error "$LCTL pool_destroy $FSNAME.$TESTNAME failed"
15664         echo "unlink $MDSOBJS files @$next_id..."
15665         unlinkmany $DIR/$tdir/f $MDSOBJS || error "unlinkmany failed"
15666
15667         if ! combined_mgs_mds ; then
15668                 umount_mgs_client
15669         fi
15670 }
15671 run_test 220 "preallocated MDS objects still used if ENOSPC from OST"
15672
15673 test_221() {
15674         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15675
15676         dd if=`which date` of=$MOUNT/date oflag=sync
15677         chmod +x $MOUNT/date
15678
15679         #define OBD_FAIL_LLITE_FAULT_TRUNC_RACE  0x1401
15680         $LCTL set_param fail_loc=0x80001401
15681
15682         $MOUNT/date > /dev/null
15683         rm -f $MOUNT/date
15684 }
15685 run_test 221 "make sure fault and truncate race to not cause OOM"
15686
15687 test_222a () {
15688         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15689
15690         rm -rf $DIR/$tdir
15691         test_mkdir $DIR/$tdir
15692         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15693         createmany -o $DIR/$tdir/$tfile 10
15694         cancel_lru_locks mdc
15695         cancel_lru_locks osc
15696         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15697         $LCTL set_param fail_loc=0x31a
15698         ls -l $DIR/$tdir > /dev/null || error "AGL for ls failed"
15699         $LCTL set_param fail_loc=0
15700         rm -r $DIR/$tdir
15701 }
15702 run_test 222a "AGL for ls should not trigger CLIO lock failure"
15703
15704 test_222b () {
15705         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15706
15707         rm -rf $DIR/$tdir
15708         test_mkdir $DIR/$tdir
15709         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15710         createmany -o $DIR/$tdir/$tfile 10
15711         cancel_lru_locks mdc
15712         cancel_lru_locks osc
15713         #define OBD_FAIL_LDLM_AGL_DELAY           0x31a
15714         $LCTL set_param fail_loc=0x31a
15715         rm -r $DIR/$tdir || error "AGL for rmdir failed"
15716         $LCTL set_param fail_loc=0
15717 }
15718 run_test 222b "AGL for rmdir should not trigger CLIO lock failure"
15719
15720 test_223 () {
15721         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15722
15723         rm -rf $DIR/$tdir
15724         test_mkdir $DIR/$tdir
15725         $LFS setstripe -c 1 -i 0 $DIR/$tdir
15726         createmany -o $DIR/$tdir/$tfile 10
15727         cancel_lru_locks mdc
15728         cancel_lru_locks osc
15729         #define OBD_FAIL_LDLM_AGL_NOLOCK          0x31b
15730         $LCTL set_param fail_loc=0x31b
15731         ls -l $DIR/$tdir > /dev/null || error "reenqueue failed"
15732         $LCTL set_param fail_loc=0
15733         rm -r $DIR/$tdir
15734 }
15735 run_test 223 "osc reenqueue if without AGL lock granted ======================="
15736
15737 test_224a() { # LU-1039, MRP-303
15738         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15739
15740         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB   0x508
15741         $LCTL set_param fail_loc=0x508
15742         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1 conv=fsync
15743         $LCTL set_param fail_loc=0
15744         df $DIR
15745 }
15746 run_test 224a "Don't panic on bulk IO failure"
15747
15748 test_224b() { # LU-1039, MRP-303
15749         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15750
15751         dd if=/dev/zero of=$DIR/$tfile bs=4096 count=1
15752         cancel_lru_locks osc
15753         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB2   0x515
15754         $LCTL set_param fail_loc=0x515
15755         dd of=/dev/null if=$DIR/$tfile bs=4096 count=1
15756         $LCTL set_param fail_loc=0
15757         df $DIR
15758 }
15759 run_test 224b "Don't panic on bulk IO failure"
15760
15761 test_224c() { # LU-6441
15762         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15763         remote_mds_nodsh && skip "remote MDS with nodsh"
15764
15765         local p="$TMP/$TESTSUITE-$TESTNAME.parameters"
15766         save_writethrough $p
15767         set_cache writethrough on
15768
15769         local pages_per_rpc=$($LCTL get_param \
15770                                 osc.*.max_pages_per_rpc)
15771         local at_max=$($LCTL get_param -n at_max)
15772         local timeout=$($LCTL get_param -n timeout)
15773         local test_at="at_max"
15774         local param_at="$FSNAME.sys.at_max"
15775         local test_timeout="timeout"
15776         local param_timeout="$FSNAME.sys.timeout"
15777
15778         $LCTL set_param -n osc.*.max_pages_per_rpc=1024
15779
15780         set_persistent_param_and_check client "$test_at" "$param_at" 0
15781         set_persistent_param_and_check client "$test_timeout" "$param_timeout" 5
15782
15783         #define OBD_FAIL_PTLRPC_CLIENT_BULK_CB3 0x520
15784         do_facet ost1 "$LCTL set_param fail_loc=0x520"
15785         $LFS setstripe -c 1 -i 0 $DIR/$tfile
15786         dd if=/dev/zero of=$DIR/$tfile bs=8MB count=1
15787         sync
15788         do_facet ost1 "$LCTL set_param fail_loc=0"
15789
15790         set_persistent_param_and_check client "$test_at" "$param_at" $at_max
15791         set_persistent_param_and_check client "$test_timeout" "$param_timeout" \
15792                 $timeout
15793
15794         $LCTL set_param -n $pages_per_rpc
15795         restore_lustre_params < $p
15796         rm -f $p
15797 }
15798 run_test 224c "Don't hang if one of md lost during large bulk RPC"
15799
15800 MDSSURVEY=${MDSSURVEY:-$(which mds-survey 2>/dev/null || true)}
15801 test_225a () {
15802         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15803         if [ -z ${MDSSURVEY} ]; then
15804                 skip_env "mds-survey not found"
15805         fi
15806         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15807                 skip "Need MDS version at least 2.2.51"
15808
15809         local mds=$(facet_host $SINGLEMDS)
15810         local target=$(do_nodes $mds 'lctl dl' |
15811                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15812
15813         local cmd1="file_count=1000 thrhi=4"
15814         local cmd2="dir_count=2 layer=mdd stripe_count=0"
15815         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15816         local cmd="$cmd1 $cmd2 $cmd3"
15817
15818         rm -f ${TMP}/mds_survey*
15819         echo + $cmd
15820         eval $cmd || error "mds-survey with zero-stripe failed"
15821         cat ${TMP}/mds_survey*
15822         rm -f ${TMP}/mds_survey*
15823 }
15824 run_test 225a "Metadata survey sanity with zero-stripe"
15825
15826 test_225b () {
15827         if [ -z ${MDSSURVEY} ]; then
15828                 skip_env "mds-survey not found"
15829         fi
15830         [ $MDS1_VERSION -ge $(version_code 2.2.51) ] ||
15831                 skip "Need MDS version at least 2.2.51"
15832         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15833         remote_mds_nodsh && skip "remote MDS with nodsh"
15834         if [ $($LCTL dl | grep -c osc) -eq 0 ]; then
15835                 skip_env "Need to mount OST to test"
15836         fi
15837
15838         local mds=$(facet_host $SINGLEMDS)
15839         local target=$(do_nodes $mds 'lctl dl' |
15840                        awk '{ if ($2 == "UP" && $3 == "mdt") { print $4 }}')
15841
15842         local cmd1="file_count=1000 thrhi=4"
15843         local cmd2="dir_count=2 layer=mdd stripe_count=1"
15844         local cmd3="rslt_loc=${TMP} targets=\"$mds:$target\" $MDSSURVEY"
15845         local cmd="$cmd1 $cmd2 $cmd3"
15846
15847         rm -f ${TMP}/mds_survey*
15848         echo + $cmd
15849         eval $cmd || error "mds-survey with stripe_count failed"
15850         cat ${TMP}/mds_survey*
15851         rm -f ${TMP}/mds_survey*
15852 }
15853 run_test 225b "Metadata survey sanity with stripe_count = 1"
15854
15855 mcreate_path2fid () {
15856         local mode=$1
15857         local major=$2
15858         local minor=$3
15859         local name=$4
15860         local desc=$5
15861         local path=$DIR/$tdir/$name
15862         local fid
15863         local rc
15864         local fid_path
15865
15866         $MCREATE --mode=$1 --major=$2 --minor=$3 $path ||
15867                 error "cannot create $desc"
15868
15869         fid=$($LFS path2fid $path | tr -d '[' | tr -d ']')
15870         rc=$?
15871         [ $rc -ne 0 ] && error "cannot get fid of a $desc"
15872
15873         fid_path=$($LFS fid2path $MOUNT $fid)
15874         rc=$?
15875         [ $rc -ne 0 ] && error "cannot get path of $desc by $DIR $path $fid"
15876
15877         [ "$path" == "$fid_path" ] ||
15878                 error "fid2path returned $fid_path, expected $path"
15879
15880         echo "pass with $path and $fid"
15881 }
15882
15883 test_226a () {
15884         rm -rf $DIR/$tdir
15885         mkdir -p $DIR/$tdir
15886
15887         mcreate_path2fid 0010666 0 0 fifo "FIFO"
15888         mcreate_path2fid 0020666 1 3 null "character special file (null)"
15889         mcreate_path2fid 0020666 1 255 none "character special file (no device)"
15890         mcreate_path2fid 0040666 0 0 dir "directory"
15891         mcreate_path2fid 0060666 7 0 loop0 "block special file (loop)"
15892         mcreate_path2fid 0100666 0 0 file "regular file"
15893         mcreate_path2fid 0120666 0 0 link "symbolic link"
15894         mcreate_path2fid 0140666 0 0 sock "socket"
15895 }
15896 run_test 226a "call path2fid and fid2path on files of all type"
15897
15898 test_226b () {
15899         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
15900
15901         local MDTIDX=1
15902
15903         rm -rf $DIR/$tdir
15904         mkdir -p $DIR/$tdir
15905         $LFS setdirstripe -i $MDTIDX $DIR/$tdir/remote_dir ||
15906                 error "create remote directory failed"
15907         mcreate_path2fid 0010666 0 0 "remote_dir/fifo" "FIFO"
15908         mcreate_path2fid 0020666 1 3 "remote_dir/null" \
15909                                 "character special file (null)"
15910         mcreate_path2fid 0020666 1 255 "remote_dir/none" \
15911                                 "character special file (no device)"
15912         mcreate_path2fid 0040666 0 0 "remote_dir/dir" "directory"
15913         mcreate_path2fid 0060666 7 0 "remote_dir/loop0" \
15914                                 "block special file (loop)"
15915         mcreate_path2fid 0100666 0 0 "remote_dir/file" "regular file"
15916         mcreate_path2fid 0120666 0 0 "remote_dir/link" "symbolic link"
15917         mcreate_path2fid 0140666 0 0 "remote_dir/sock" "socket"
15918 }
15919 run_test 226b "call path2fid and fid2path on files of all type under remote dir"
15920
15921 # LU-1299 Executing or running ldd on a truncated executable does not
15922 # cause an out-of-memory condition.
15923 test_227() {
15924         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15925         [ -z "$(which ldd)" ] && skip_env "should have ldd tool"
15926
15927         dd if=$(which date) of=$MOUNT/date bs=1k count=1
15928         chmod +x $MOUNT/date
15929
15930         $MOUNT/date > /dev/null
15931         ldd $MOUNT/date > /dev/null
15932         rm -f $MOUNT/date
15933 }
15934 run_test 227 "running truncated executable does not cause OOM"
15935
15936 # LU-1512 try to reuse idle OI blocks
15937 test_228a() {
15938         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15939         remote_mds_nodsh && skip "remote MDS with nodsh"
15940         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15941
15942         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15943         local myDIR=$DIR/$tdir
15944
15945         mkdir -p $myDIR
15946         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15947         $LCTL set_param fail_loc=0x80001002
15948         createmany -o $myDIR/t- 10000
15949         $LCTL set_param fail_loc=0
15950         # The guard is current the largest FID holder
15951         touch $myDIR/guard
15952         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15953                     tr -d '[')
15954         local IDX=$(($SEQ % 64))
15955
15956         do_facet $SINGLEMDS sync
15957         # Make sure journal flushed.
15958         sleep 6
15959         local blk1=$(do_facet $SINGLEMDS \
15960                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15961                      grep Blockcount | awk '{print $4}')
15962
15963         # Remove old files, some OI blocks will become idle.
15964         unlinkmany $myDIR/t- 10000
15965         # Create new files, idle OI blocks should be reused.
15966         createmany -o $myDIR/t- 2000
15967         do_facet $SINGLEMDS sync
15968         # Make sure journal flushed.
15969         sleep 6
15970         local blk2=$(do_facet $SINGLEMDS \
15971                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
15972                      grep Blockcount | awk '{print $4}')
15973
15974         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
15975 }
15976 run_test 228a "try to reuse idle OI blocks"
15977
15978 test_228b() {
15979         [ $PARALLEL == "yes" ] && skip "skip parallel run"
15980         remote_mds_nodsh && skip "remote MDS with nodsh"
15981         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
15982
15983         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
15984         local myDIR=$DIR/$tdir
15985
15986         mkdir -p $myDIR
15987         #define OBD_FAIL_SEQ_EXHAUST             0x1002
15988         $LCTL set_param fail_loc=0x80001002
15989         createmany -o $myDIR/t- 10000
15990         $LCTL set_param fail_loc=0
15991         # The guard is current the largest FID holder
15992         touch $myDIR/guard
15993         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
15994                     tr -d '[')
15995         local IDX=$(($SEQ % 64))
15996
15997         do_facet $SINGLEMDS sync
15998         # Make sure journal flushed.
15999         sleep 6
16000         local blk1=$(do_facet $SINGLEMDS \
16001                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16002                      grep Blockcount | awk '{print $4}')
16003
16004         # Remove old files, some OI blocks will become idle.
16005         unlinkmany $myDIR/t- 10000
16006
16007         # stop the MDT
16008         stop $SINGLEMDS || error "Fail to stop MDT."
16009         # remount the MDT
16010         start $SINGLEMDS $MDT_DEV $MDS_MOUNT_OPTS || error "Fail to start MDT."
16011
16012         df $MOUNT || error "Fail to df."
16013         # Create new files, idle OI blocks should be reused.
16014         createmany -o $myDIR/t- 2000
16015         do_facet $SINGLEMDS sync
16016         # Make sure journal flushed.
16017         sleep 6
16018         local blk2=$(do_facet $SINGLEMDS \
16019                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16020                      grep Blockcount | awk '{print $4}')
16021
16022         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16023 }
16024 run_test 228b "idle OI blocks can be reused after MDT restart"
16025
16026 #LU-1881
16027 test_228c() {
16028         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16029         remote_mds_nodsh && skip "remote MDS with nodsh"
16030         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
16031
16032         local MDT_DEV=$(mdsdevname ${SINGLEMDS//mds/})
16033         local myDIR=$DIR/$tdir
16034
16035         mkdir -p $myDIR
16036         #define OBD_FAIL_SEQ_EXHAUST             0x1002
16037         $LCTL set_param fail_loc=0x80001002
16038         # 20000 files can guarantee there are index nodes in the OI file
16039         createmany -o $myDIR/t- 20000
16040         $LCTL set_param fail_loc=0
16041         # The guard is current the largest FID holder
16042         touch $myDIR/guard
16043         local SEQ=$($LFS path2fid $myDIR/guard | awk -F ':' '{print $1}' |
16044                     tr -d '[')
16045         local IDX=$(($SEQ % 64))
16046
16047         do_facet $SINGLEMDS sync
16048         # Make sure journal flushed.
16049         sleep 6
16050         local blk1=$(do_facet $SINGLEMDS \
16051                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16052                      grep Blockcount | awk '{print $4}')
16053
16054         # Remove old files, some OI blocks will become idle.
16055         unlinkmany $myDIR/t- 20000
16056         rm -f $myDIR/guard
16057         # The OI file should become empty now
16058
16059         # Create new files, idle OI blocks should be reused.
16060         createmany -o $myDIR/t- 2000
16061         do_facet $SINGLEMDS sync
16062         # Make sure journal flushed.
16063         sleep 6
16064         local blk2=$(do_facet $SINGLEMDS \
16065                      "$DEBUGFS -c -R \\\"stat oi.16.${IDX}\\\" $MDT_DEV" |
16066                      grep Blockcount | awk '{print $4}')
16067
16068         [ $blk1 == $blk2 ] || error "old blk1=$blk1, new blk2=$blk2, unmatched!"
16069 }
16070 run_test 228c "NOT shrink the last entry in OI index node to recycle idle leaf"
16071
16072 test_229() { # LU-2482, LU-3448
16073         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16074         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
16075         [ $MDS1_VERSION -lt $(version_code 2.4.53) ] &&
16076                 skip "No HSM $(lustre_build_version $SINGLEMDS) MDS < 2.4.53"
16077
16078         rm -f $DIR/$tfile
16079
16080         # Create a file with a released layout and stripe count 2.
16081         $MULTIOP $DIR/$tfile H2c ||
16082                 error "failed to create file with released layout"
16083
16084         $LFS getstripe -v $DIR/$tfile
16085
16086         local pattern=$($LFS getstripe -L $DIR/$tfile)
16087         [ X"$pattern" = X"released" ] || error "pattern error ($pattern)"
16088
16089         local stripe_count=$($LFS getstripe -c $DIR/$tfile) ||
16090                 error "getstripe"
16091         [ $stripe_count -eq 2 ] || error "stripe count not 2 ($stripe_count)"
16092         stat $DIR/$tfile || error "failed to stat released file"
16093
16094         chown $RUNAS_ID $DIR/$tfile ||
16095                 error "chown $RUNAS_ID $DIR/$tfile failed"
16096
16097         chgrp $RUNAS_ID $DIR/$tfile ||
16098                 error "chgrp $RUNAS_ID $DIR/$tfile failed"
16099
16100         touch $DIR/$tfile || error "touch $DIR/$tfile failed"
16101         rm $DIR/$tfile || error "failed to remove released file"
16102 }
16103 run_test 229 "getstripe/stat/rm/attr changes work on released files"
16104
16105 test_230a() {
16106         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16107         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16108         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16109                 skip "Need MDS version at least 2.11.52"
16110
16111         local MDTIDX=1
16112
16113         test_mkdir $DIR/$tdir
16114         test_mkdir -i0 -c1 $DIR/$tdir/test_230_local
16115         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230_local)
16116         [ $mdt_idx -ne 0 ] &&
16117                 error "create local directory on wrong MDT $mdt_idx"
16118
16119         $LFS mkdir -i $MDTIDX $DIR/$tdir/test_230 ||
16120                         error "create remote directory failed"
16121         local mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230)
16122         [ $mdt_idx -ne $MDTIDX ] &&
16123                 error "create remote directory on wrong MDT $mdt_idx"
16124
16125         createmany -o $DIR/$tdir/test_230/t- 10 ||
16126                 error "create files on remote directory failed"
16127         mdt_idx=$($LFS getstripe -m $DIR/$tdir/test_230/t-0)
16128         [ $mdt_idx -ne $MDTIDX ] && error "create files on wrong MDT $mdt_idx"
16129         rm -r $DIR/$tdir || error "unlink remote directory failed"
16130 }
16131 run_test 230a "Create remote directory and files under the remote directory"
16132
16133 test_230b() {
16134         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16135         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16136         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16137                 skip "Need MDS version at least 2.11.52"
16138
16139         local MDTIDX=1
16140         local mdt_index
16141         local i
16142         local file
16143         local pid
16144         local stripe_count
16145         local migrate_dir=$DIR/$tdir/migrate_dir
16146         local other_dir=$DIR/$tdir/other_dir
16147
16148         test_mkdir $DIR/$tdir
16149         test_mkdir -i0 -c1 $migrate_dir
16150         test_mkdir -i0 -c1 $other_dir
16151         for ((i=0; i<10; i++)); do
16152                 mkdir -p $migrate_dir/dir_${i}
16153                 createmany -o $migrate_dir/dir_${i}/f 10 ||
16154                         error "create files under remote dir failed $i"
16155         done
16156
16157         cp /etc/passwd $migrate_dir/$tfile
16158         cp /etc/passwd $other_dir/$tfile
16159         chattr +SAD $migrate_dir
16160         chattr +SAD $migrate_dir/$tfile
16161
16162         local old_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16163         local old_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16164         local old_dir_mode=$(stat -c%f $migrate_dir)
16165         local old_file_mode=$(stat -c%f $migrate_dir/$tfile)
16166
16167         mkdir -p $migrate_dir/dir_default_stripe2
16168         $LFS setstripe -c 2 $migrate_dir/dir_default_stripe2
16169         $LFS setstripe -c 2 $migrate_dir/${tfile}_stripe2
16170
16171         mkdir -p $other_dir
16172         ln $migrate_dir/$tfile $other_dir/luna
16173         ln $migrate_dir/$tfile $migrate_dir/sofia
16174         ln $other_dir/$tfile $migrate_dir/david
16175         ln -s $migrate_dir/$tfile $other_dir/zachary
16176         ln -s $migrate_dir/$tfile $migrate_dir/${tfile}_ln
16177         ln -s $other_dir/$tfile $migrate_dir/${tfile}_ln_other
16178
16179         $LFS migrate -m $MDTIDX $migrate_dir ||
16180                 error "fails on migrating remote dir to MDT1"
16181
16182         echo "migratate to MDT1, then checking.."
16183         for ((i = 0; i < 10; i++)); do
16184                 for file in $(find $migrate_dir/dir_${i}); do
16185                         mdt_index=$($LFS getstripe -m $file)
16186                         [ $mdt_index == $MDTIDX ] ||
16187                                 error "$file is not on MDT${MDTIDX}"
16188                 done
16189         done
16190
16191         # the multiple link file should still in MDT0
16192         mdt_index=$($LFS getstripe -m $migrate_dir/$tfile)
16193         [ $mdt_index == 0 ] ||
16194                 error "$file is not on MDT${MDTIDX}"
16195
16196         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16197         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16198                 error " expect $old_dir_flag get $new_dir_flag"
16199
16200         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16201         [ "$old_file_flag" = "$new_file_flag" ] ||
16202                 error " expect $old_file_flag get $new_file_flag"
16203
16204         local new_dir_mode=$(stat -c%f $migrate_dir)
16205         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16206                 error "expect mode $old_dir_mode get $new_dir_mode"
16207
16208         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16209         [ "$old_file_mode" = "$new_file_mode" ] ||
16210                 error "expect mode $old_file_mode get $new_file_mode"
16211
16212         diff /etc/passwd $migrate_dir/$tfile ||
16213                 error "$tfile different after migration"
16214
16215         diff /etc/passwd $other_dir/luna ||
16216                 error "luna different after migration"
16217
16218         diff /etc/passwd $migrate_dir/sofia ||
16219                 error "sofia different after migration"
16220
16221         diff /etc/passwd $migrate_dir/david ||
16222                 error "david different after migration"
16223
16224         diff /etc/passwd $other_dir/zachary ||
16225                 error "zachary different after migration"
16226
16227         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16228                 error "${tfile}_ln different after migration"
16229
16230         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16231                 error "${tfile}_ln_other different after migration"
16232
16233         stripe_count=$($LFS getstripe -c $migrate_dir/dir_default_stripe2)
16234         [ $stripe_count = 2 ] ||
16235                 error "dir strpe_count $d != 2 after migration."
16236
16237         stripe_count=$($LFS getstripe -c $migrate_dir/${tfile}_stripe2)
16238         [ $stripe_count = 2 ] ||
16239                 error "file strpe_count $d != 2 after migration."
16240
16241         #migrate back to MDT0
16242         MDTIDX=0
16243
16244         $LFS migrate -m $MDTIDX $migrate_dir ||
16245                 error "fails on migrating remote dir to MDT0"
16246
16247         echo "migrate back to MDT0, checking.."
16248         for file in $(find $migrate_dir); do
16249                 mdt_index=$($LFS getstripe -m $file)
16250                 [ $mdt_index == $MDTIDX ] ||
16251                         error "$file is not on MDT${MDTIDX}"
16252         done
16253
16254         local new_dir_flag=$(lsattr -a $migrate_dir | awk '/\/\.$/ {print $1}')
16255         [ "$old_dir_flag" = "$new_dir_flag" ] ||
16256                 error " expect $old_dir_flag get $new_dir_flag"
16257
16258         local new_file_flag=$(lsattr $migrate_dir/$tfile | awk '{print $1}')
16259         [ "$old_file_flag" = "$new_file_flag" ] ||
16260                 error " expect $old_file_flag get $new_file_flag"
16261
16262         local new_dir_mode=$(stat -c%f $migrate_dir)
16263         [ "$old_dir_mode" = "$new_dir_mode" ] ||
16264                 error "expect mode $old_dir_mode get $new_dir_mode"
16265
16266         local new_file_mode=$(stat -c%f $migrate_dir/$tfile)
16267         [ "$old_file_mode" = "$new_file_mode" ] ||
16268                 error "expect mode $old_file_mode get $new_file_mode"
16269
16270         diff /etc/passwd ${migrate_dir}/$tfile ||
16271                 error "$tfile different after migration"
16272
16273         diff /etc/passwd ${other_dir}/luna ||
16274                 error "luna different after migration"
16275
16276         diff /etc/passwd ${migrate_dir}/sofia ||
16277                 error "sofia different after migration"
16278
16279         diff /etc/passwd ${other_dir}/zachary ||
16280                 error "zachary different after migration"
16281
16282         diff /etc/passwd $migrate_dir/${tfile}_ln ||
16283                 error "${tfile}_ln different after migration"
16284
16285         diff /etc/passwd $migrate_dir/${tfile}_ln_other ||
16286                 error "${tfile}_ln_other different after migration"
16287
16288         stripe_count=$($LFS getstripe -c ${migrate_dir}/dir_default_stripe2)
16289         [ $stripe_count = 2 ] ||
16290                 error "dir strpe_count $d != 2 after migration."
16291
16292         stripe_count=$($LFS getstripe -c ${migrate_dir}/${tfile}_stripe2)
16293         [ $stripe_count = 2 ] ||
16294                 error "file strpe_count $d != 2 after migration."
16295
16296         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16297 }
16298 run_test 230b "migrate directory"
16299
16300 test_230c() {
16301         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16302         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16303         remote_mds_nodsh && skip "remote MDS with nodsh"
16304         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16305                 skip "Need MDS version at least 2.11.52"
16306
16307         local MDTIDX=1
16308         local total=3
16309         local mdt_index
16310         local file
16311         local migrate_dir=$DIR/$tdir/migrate_dir
16312
16313         #If migrating directory fails in the middle, all entries of
16314         #the directory is still accessiable.
16315         test_mkdir $DIR/$tdir
16316         test_mkdir -i0 -c1 $migrate_dir
16317         test_mkdir -i1 -c1 $DIR/$tdir/remote_dir
16318         stat $migrate_dir
16319         createmany -o $migrate_dir/f $total ||
16320                 error "create files under ${migrate_dir} failed"
16321
16322         # fail after migrating top dir, and this will fail only once, so the
16323         # first sub file migration will fail (currently f3), others succeed.
16324         #OBD_FAIL_MIGRATE_ENTRIES       0x1801
16325         do_facet mds1 lctl set_param fail_loc=0x1801
16326         local t=$(ls $migrate_dir | wc -l)
16327         $LFS migrate --mdt-index $MDTIDX $migrate_dir &&
16328                 error "migrate should fail"
16329         local u=$(ls $migrate_dir | wc -l)
16330         [ "$u" == "$t" ] || error "$u != $t during migration"
16331
16332         # add new dir/file should succeed
16333         mkdir $migrate_dir/dir ||
16334                 error "mkdir failed under migrating directory"
16335         touch $migrate_dir/file ||
16336                 error "create file failed under migrating directory"
16337
16338         # add file with existing name should fail
16339         for file in $migrate_dir/f*; do
16340                 stat $file > /dev/null || error "stat $file failed"
16341                 $OPENFILE -f O_CREAT:O_EXCL $file &&
16342                         error "open(O_CREAT|O_EXCL) $file should fail"
16343                 $MULTIOP $file m && error "create $file should fail"
16344                 touch $DIR/$tdir/remote_dir/$tfile ||
16345                         error "touch $tfile failed"
16346                 ln $DIR/$tdir/remote_dir/$tfile $file &&
16347                         error "link $file should fail"
16348                 mdt_index=$($LFS getstripe -m $file)
16349                 if [ $mdt_index == 0 ]; then
16350                         # file failed to migrate is not allowed to rename to
16351                         mv $DIR/$tdir/remote_dir/$tfile $file &&
16352                                 error "rename to $file should fail"
16353                 else
16354                         mv $DIR/$tdir/remote_dir/$tfile $file ||
16355                                 error "rename to $file failed"
16356                 fi
16357                 echo hello >> $file || error "write $file failed"
16358         done
16359
16360         # resume migration with different options should fail
16361         $LFS migrate -m 0 $migrate_dir &&
16362                 error "migrate -m 0 $migrate_dir should fail"
16363
16364         $LFS migrate -m $MDTIDX -c 2 $migrate_dir &&
16365                 error "migrate -c 2 $migrate_dir should fail"
16366
16367         # resume migration should succeed
16368         $LFS migrate -m $MDTIDX $migrate_dir ||
16369                 error "migrate $migrate_dir failed"
16370
16371         echo "Finish migration, then checking.."
16372         for file in $(find $migrate_dir); do
16373                 mdt_index=$($LFS getstripe -m $file)
16374                 [ $mdt_index == $MDTIDX ] ||
16375                         error "$file is not on MDT${MDTIDX}"
16376         done
16377
16378         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16379 }
16380 run_test 230c "check directory accessiblity if migration failed"
16381
16382 test_230d() {
16383         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16384         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16385         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16386                 skip "Need MDS version at least 2.11.52"
16387         # LU-11235
16388         [ "$mds1_FSTYPE" == "zfs" ] && skip "skip ZFS backend"
16389
16390         local migrate_dir=$DIR/$tdir/migrate_dir
16391         local old_index
16392         local new_index
16393         local old_count
16394         local new_count
16395         local new_hash
16396         local mdt_index
16397         local i
16398         local j
16399
16400         old_index=$((RANDOM % MDSCOUNT))
16401         old_count=$((MDSCOUNT - old_index))
16402         new_index=$((RANDOM % MDSCOUNT))
16403         new_count=$((MDSCOUNT - new_index))
16404         new_hash="all_char"
16405
16406         [ $old_count -gt 1 ] && old_count=$((old_count - RANDOM % old_count))
16407         [ $new_count -gt 1 ] && new_count=$((new_count - RANDOM % new_count))
16408
16409         test_mkdir $DIR/$tdir
16410         test_mkdir -i $old_index -c $old_count $migrate_dir
16411
16412         for ((i=0; i<100; i++)); do
16413                 test_mkdir -i0 -c1 $migrate_dir/dir_${i}
16414                 createmany -o $migrate_dir/dir_${i}/f 100 ||
16415                         error "create files under remote dir failed $i"
16416         done
16417
16418         echo -n "Migrate from MDT$old_index "
16419         [ $old_count -gt 1 ] && echo -n "... MDT$((old_index + old_count - 1)) "
16420         echo -n "to MDT$new_index"
16421         [ $new_count -gt 1 ] && echo -n " ... MDT$((new_index + new_count - 1))"
16422         echo
16423
16424         echo "$LFS migrate -m$new_index -c$new_count -H $new_hash $migrate_dir"
16425         $LFS migrate -m $new_index -c $new_count -H $new_hash $migrate_dir ||
16426                 error "migrate remote dir error"
16427
16428         echo "Finish migration, then checking.."
16429         for file in $(find $migrate_dir); do
16430                 mdt_index=$($LFS getstripe -m $file)
16431                 if [ $mdt_index -lt $new_index ] ||
16432                    [ $mdt_index -gt $((new_index + new_count - 1)) ]; then
16433                         error "$file is on MDT$mdt_index"
16434                 fi
16435         done
16436
16437         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16438 }
16439 run_test 230d "check migrate big directory"
16440
16441 test_230e() {
16442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16443         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16444         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16445                 skip "Need MDS version at least 2.11.52"
16446
16447         local i
16448         local j
16449         local a_fid
16450         local b_fid
16451
16452         mkdir -p $DIR/$tdir
16453         mkdir $DIR/$tdir/migrate_dir
16454         mkdir $DIR/$tdir/other_dir
16455         touch $DIR/$tdir/migrate_dir/a
16456         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/b
16457         ls $DIR/$tdir/other_dir
16458
16459         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16460                 error "migrate dir fails"
16461
16462         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16463         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16464
16465         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16466         [ $mdt_index == 0 ] || error "a is not on MDT0"
16467
16468         $LFS migrate -m 1 $DIR/$tdir/other_dir ||
16469                 error "migrate dir fails"
16470
16471         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir)
16472         [ $mdt_index == 1 ] || error "other_dir is not on MDT1"
16473
16474         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16475         [ $mdt_index == 1 ] || error "a is not on MDT1"
16476
16477         mdt_index=$($LFS getstripe -m $DIR/$tdir/other_dir/b)
16478         [ $mdt_index == 1 ] || error "b is not on MDT1"
16479
16480         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16481         b_fid=$($LFS path2fid $DIR/$tdir/other_dir/b)
16482
16483         [ "$a_fid" = "$b_fid" ] || error "different fid after migration"
16484
16485         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16486 }
16487 run_test 230e "migrate mulitple local link files"
16488
16489 test_230f() {
16490         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16491         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16492         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16493                 skip "Need MDS version at least 2.11.52"
16494
16495         local a_fid
16496         local ln_fid
16497
16498         mkdir -p $DIR/$tdir
16499         mkdir $DIR/$tdir/migrate_dir
16500         $LFS mkdir -i1 $DIR/$tdir/other_dir
16501         touch $DIR/$tdir/migrate_dir/a
16502         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln1
16503         ln $DIR/$tdir/migrate_dir/a $DIR/$tdir/other_dir/ln2
16504         ls $DIR/$tdir/other_dir
16505
16506         # a should be migrated to MDT1, since no other links on MDT0
16507         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16508                 error "#1 migrate dir fails"
16509         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir)
16510         [ $mdt_index == 1 ] || error "migrate_dir is not on MDT1"
16511         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16512         [ $mdt_index == 1 ] || error "a is not on MDT1"
16513
16514         # a should stay on MDT1, because it is a mulitple link file
16515         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16516                 error "#2 migrate dir fails"
16517         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16518         [ $mdt_index == 1 ] || error "a is not on MDT1"
16519
16520         $LFS migrate -m 1 $DIR/$tdir/migrate_dir ||
16521                 error "#3 migrate dir fails"
16522
16523         a_fid=$($LFS path2fid $DIR/$tdir/migrate_dir/a)
16524         ln_fid=$($LFS path2fid $DIR/$tdir/other_dir/ln1)
16525         [ "$a_fid" = "$ln_fid" ] || error "different fid after migrate to MDT1"
16526
16527         rm -rf $DIR/$tdir/other_dir/ln1 || error "unlink ln1 fails"
16528         rm -rf $DIR/$tdir/other_dir/ln2 || error "unlink ln2 fails"
16529
16530         # a should be migrated to MDT0, since no other links on MDT1
16531         $LFS migrate -m 0 $DIR/$tdir/migrate_dir ||
16532                 error "#4 migrate dir fails"
16533         mdt_index=$($LFS getstripe -m $DIR/$tdir/migrate_dir/a)
16534         [ $mdt_index == 0 ] || error "a is not on MDT0"
16535
16536         rm -rf $DIR/$tdir || error "rm dir failed after migration"
16537 }
16538 run_test 230f "migrate mulitple remote link files"
16539
16540 test_230g() {
16541         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16542         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16543         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16544                 skip "Need MDS version at least 2.11.52"
16545
16546         mkdir -p $DIR/$tdir/migrate_dir
16547
16548         $LFS migrate -m 1000 $DIR/$tdir/migrate_dir &&
16549                 error "migrating dir to non-exist MDT succeeds"
16550         true
16551 }
16552 run_test 230g "migrate dir to non-exist MDT"
16553
16554 test_230h() {
16555         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16556         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16557         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16558                 skip "Need MDS version at least 2.11.52"
16559
16560         local mdt_index
16561
16562         mkdir -p $DIR/$tdir/migrate_dir
16563
16564         $LFS migrate -m1 $DIR &&
16565                 error "migrating mountpoint1 should fail"
16566
16567         $LFS migrate -m1 $DIR/$tdir/.. &&
16568                 error "migrating mountpoint2 should fail"
16569
16570         # same as mv
16571         $LFS migrate -m1 $DIR/$tdir/migrate_dir/.. &&
16572                 error "migrating $tdir/migrate_dir/.. should fail"
16573
16574         true
16575 }
16576 run_test 230h "migrate .. and root"
16577
16578 test_230i() {
16579         [ $PARALLEL == "yes" ] && skip "skip parallel run"
16580         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16581         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16582                 skip "Need MDS version at least 2.11.52"
16583
16584         mkdir -p $DIR/$tdir/migrate_dir
16585
16586         $LFS migrate -m 1 $DIR/$tdir/migrate_dir/ ||
16587                 error "migration fails with a tailing slash"
16588
16589         $LFS migrate -m 0 $DIR/$tdir/migrate_dir// ||
16590                 error "migration fails with two tailing slashes"
16591 }
16592 run_test 230i "lfs migrate -m tolerates trailing slashes"
16593
16594 test_230j() {
16595         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16596         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
16597                 skip "Need MDS version at least 2.11.52"
16598
16599         $LFS mkdir -m 0 -c 1 $DIR/$tdir || error "mkdir $tdir failed"
16600         $LFS setstripe -E 1M -L mdt $DIR/$tdir/$tfile ||
16601                 error "create $tfile failed"
16602         cat /etc/passwd > $DIR/$tdir/$tfile
16603
16604         $LFS migrate -m 1 $DIR/$tdir
16605
16606         cmp /etc/passwd $DIR/$tdir/$tfile ||
16607                 error "DoM file mismatch after migration"
16608 }
16609 run_test 230j "DoM file data not changed after dir migration"
16610
16611 test_230k() {
16612         [ $MDSCOUNT -lt 4 ] && skip "needs >= 4 MDTs"
16613         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16614                 skip "Need MDS version at least 2.11.56"
16615
16616         local total=20
16617         local files_on_starting_mdt=0
16618
16619         $LFS mkdir -i -1 -c 2 $DIR/$tdir || error "mkdir failed"
16620         $LFS getdirstripe $DIR/$tdir
16621         for i in $(seq $total); do
16622                 echo $((i*i - i)) > $DIR/$tdir/$tfile.$i || error "write failed"
16623                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16624                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16625         done
16626
16627         echo "$files_on_starting_mdt files on MDT0"
16628
16629         $LFS migrate -m 1,3 $DIR/$tdir || error "migrate -m 1,3 failed"
16630         $LFS getdirstripe $DIR/$tdir
16631
16632         files_on_starting_mdt=0
16633         for i in $(seq $total); do
16634                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16635                         error "file $tfile.$i mismatch after migration"
16636                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 1 ]] &&
16637                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16638         done
16639
16640         echo "$files_on_starting_mdt files on MDT1 after migration"
16641         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT1"
16642
16643         $LFS migrate -m 0 -c 2 $DIR/$tdir || error "migrate -m 0 -c 2 failed"
16644         $LFS getdirstripe $DIR/$tdir
16645
16646         files_on_starting_mdt=0
16647         for i in $(seq $total); do
16648                 $(echo $((i*i - i)) | cmp $DIR/$tdir/$tfile.$i -) ||
16649                         error "file $tfile.$i mismatch after 2nd migration"
16650                 [[ $($LFS getstripe -m $DIR/$tdir/$tfile.$i) -eq 0 ]] &&
16651                         files_on_starting_mdt=$((files_on_starting_mdt + 1))
16652         done
16653
16654         echo "$files_on_starting_mdt files on MDT0 after 2nd migration"
16655         [[ $files_on_starting_mdt -eq $total ]] && error "all files on MDT0"
16656
16657         true
16658 }
16659 run_test 230k "file data not changed after dir migration"
16660
16661 test_230l() {
16662         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
16663         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
16664                 skip "Need MDS version at least 2.11.56"
16665
16666         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "mkdir failed"
16667         createmany -o $DIR/$tdir/f___________________________________ 1000 ||
16668                 error "create files under remote dir failed $i"
16669         $LFS migrate -m 1 $DIR/$tdir || error "migrate failed"
16670 }
16671 run_test 230l "readdir between MDTs won't crash"
16672
16673 test_231a()
16674 {
16675         # For simplicity this test assumes that max_pages_per_rpc
16676         # is the same across all OSCs
16677         local max_pages=$($LCTL get_param -n osc.*.max_pages_per_rpc | head -n1)
16678         local bulk_size=$((max_pages * PAGE_SIZE))
16679         local brw_size=$(do_facet ost1 $LCTL get_param -n obdfilter.*.brw_size |
16680                                        head -n 1)
16681
16682         mkdir -p $DIR/$tdir
16683         $LFS setstripe -S ${brw_size}M $DIR/$tdir ||
16684                 error "failed to set stripe with -S ${brw_size}M option"
16685
16686         # clear the OSC stats
16687         $LCTL set_param osc.*.stats=0 &>/dev/null
16688         stop_writeback
16689
16690         # Client writes $bulk_size - there must be 1 rpc for $max_pages.
16691         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=$bulk_size count=1 \
16692                 oflag=direct &>/dev/null || error "dd failed"
16693
16694         sync; sleep 1; sync # just to be safe
16695         local nrpcs=$($LCTL get_param osc.*.stats |awk '/ost_write/ {print $2}')
16696         if [ x$nrpcs != "x1" ]; then
16697                 $LCTL get_param osc.*.stats
16698                 error "found $nrpcs ost_write RPCs, not 1 as expected"
16699         fi
16700
16701         start_writeback
16702         # Drop the OSC cache, otherwise we will read from it
16703         cancel_lru_locks osc
16704
16705         # clear the OSC stats
16706         $LCTL set_param osc.*.stats=0 &>/dev/null
16707
16708         # Client reads $bulk_size.
16709         dd if=$DIR/$tdir/$tfile of=/dev/null bs=$bulk_size count=1 \
16710                 iflag=direct &>/dev/null || error "dd failed"
16711
16712         nrpcs=$($LCTL get_param osc.*.stats | awk '/ost_read/ { print $2 }')
16713         if [ x$nrpcs != "x1" ]; then
16714                 $LCTL get_param osc.*.stats
16715                 error "found $nrpcs ost_read RPCs, not 1 as expected"
16716         fi
16717 }
16718 run_test 231a "checking that reading/writing of BRW RPC size results in one RPC"
16719
16720 test_231b() {
16721         mkdir -p $DIR/$tdir
16722         local i
16723         for i in {0..1023}; do
16724                 dd if=/dev/zero of=$DIR/$tdir/$tfile conv=notrunc \
16725                         seek=$((2 * i)) bs=4096 count=1 &>/dev/null ||
16726                         error "dd of=$DIR/$tdir/$tfile seek=$((2 * i)) failed"
16727         done
16728         sync
16729 }
16730 run_test 231b "must not assert on fully utilized OST request buffer"
16731
16732 test_232a() {
16733         mkdir -p $DIR/$tdir
16734         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16735
16736         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16737         do_facet ost1 $LCTL set_param fail_loc=0x31c
16738
16739         # ignore dd failure
16740         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1 || true
16741
16742         do_facet ost1 $LCTL set_param fail_loc=0
16743         umount_client $MOUNT || error "umount failed"
16744         mount_client $MOUNT || error "mount failed"
16745         stop ost1 || error "cannot stop ost1"
16746         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16747 }
16748 run_test 232a "failed lock should not block umount"
16749
16750 test_232b() {
16751         [ $MDS1_VERSION -ge $(version_code 2.10.58) ] ||
16752                 skip "Need MDS version at least 2.10.58"
16753
16754         mkdir -p $DIR/$tdir
16755         $LFS setstripe -c1 -i0 $DIR/$tdir/$tfile
16756         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=1
16757         sync
16758         cancel_lru_locks osc
16759
16760         #define OBD_FAIL_LDLM_OST_LVB            0x31c
16761         do_facet ost1 $LCTL set_param fail_loc=0x31c
16762
16763         # ignore failure
16764         $LFS data_version $DIR/$tdir/$tfile || true
16765
16766         do_facet ost1 $LCTL set_param fail_loc=0
16767         umount_client $MOUNT || error "umount failed"
16768         mount_client $MOUNT || error "mount failed"
16769         stop ost1 || error "cannot stop ost1"
16770         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
16771 }
16772 run_test 232b "failed data version lock should not block umount"
16773
16774 test_233a() {
16775         [ $MDS1_VERSION -ge $(version_code 2.3.64) ] ||
16776                 skip "Need MDS version at least 2.3.64"
16777         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16778
16779         local fid=$($LFS path2fid $MOUNT)
16780
16781         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16782                 error "cannot access $MOUNT using its FID '$fid'"
16783 }
16784 run_test 233a "checking that OBF of the FS root succeeds"
16785
16786 test_233b() {
16787         [ $MDS1_VERSION -ge $(version_code 2.5.90) ] ||
16788                 skip "Need MDS version at least 2.5.90"
16789         [ -n "$FILESET" ] && skip_env "SKIP due to FILESET set"
16790
16791         local fid=$($LFS path2fid $MOUNT/.lustre)
16792
16793         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16794                 error "cannot access $MOUNT/.lustre using its FID '$fid'"
16795
16796         fid=$($LFS path2fid $MOUNT/.lustre/fid)
16797         stat $MOUNT/.lustre/fid/$fid > /dev/null ||
16798                 error "cannot access $MOUNT/.lustre/fid using its FID '$fid'"
16799 }
16800 run_test 233b "checking that OBF of the FS .lustre succeeds"
16801
16802 test_234() {
16803         local p="$TMP/sanityN-$TESTNAME.parameters"
16804         save_lustre_params client "llite.*.xattr_cache" > $p
16805         lctl set_param llite.*.xattr_cache 1 ||
16806                 skip_env "xattr cache is not supported"
16807
16808         mkdir -p $DIR/$tdir || error "mkdir failed"
16809         touch $DIR/$tdir/$tfile || error "touch failed"
16810         # OBD_FAIL_LLITE_XATTR_ENOMEM
16811         $LCTL set_param fail_loc=0x1405
16812         getfattr -n user.attr $DIR/$tdir/$tfile &&
16813                 error "getfattr should have failed with ENOMEM"
16814         $LCTL set_param fail_loc=0x0
16815         rm -rf $DIR/$tdir
16816
16817         restore_lustre_params < $p
16818         rm -f $p
16819 }
16820 run_test 234 "xattr cache should not crash on ENOMEM"
16821
16822 test_235() {
16823         [ $MDS1_VERSION -lt $(version_code 2.4.52) ] &&
16824                 skip "Need MDS version at least 2.4.52"
16825
16826         flock_deadlock $DIR/$tfile
16827         local RC=$?
16828         case $RC in
16829                 0)
16830                 ;;
16831                 124) error "process hangs on a deadlock"
16832                 ;;
16833                 *) error "error executing flock_deadlock $DIR/$tfile"
16834                 ;;
16835         esac
16836 }
16837 run_test 235 "LU-1715: flock deadlock detection does not work properly"
16838
16839 #LU-2935
16840 test_236() {
16841         check_swap_layouts_support
16842
16843         local ref1=/etc/passwd
16844         local ref2=/etc/group
16845         local file1=$DIR/$tdir/f1
16846         local file2=$DIR/$tdir/f2
16847
16848         test_mkdir -c1 $DIR/$tdir
16849         $LFS setstripe -c 1 $file1 || error "cannot setstripe on '$file1': rc = $?"
16850         cp $ref1 $file1 || error "cp $ref1 $file1 failed: rc = $?"
16851         $LFS setstripe -c 2 $file2 || error "cannot setstripe on '$file2': rc = $?"
16852         cp $ref2 $file2 || error "cp $ref2 $file2 failed: rc = $?"
16853         local fd=$(free_fd)
16854         local cmd="exec $fd<>$file2"
16855         eval $cmd
16856         rm $file2
16857         $LFS swap_layouts $file1 /proc/self/fd/${fd} ||
16858                 error "cannot swap layouts of '$file1' and /proc/self/fd/${fd}"
16859         cmd="exec $fd>&-"
16860         eval $cmd
16861         cmp $ref2 $file1 || error "content compare failed ($ref2 != $file1)"
16862
16863         #cleanup
16864         rm -rf $DIR/$tdir
16865 }
16866 run_test 236 "Layout swap on open unlinked file"
16867
16868 # LU-4659 linkea consistency
16869 test_238() {
16870         [[ $MDS1_VERSION -gt $(version_code 2.5.57) ]] ||
16871                 [[ $MDS1_VERSION -gt $(version_code 2.5.1) &&
16872                    $MDS1_VERSION -lt $(version_code 2.5.50) ]] ||
16873                 skip "Need MDS version at least 2.5.58 or 2.5.2+"
16874
16875         touch $DIR/$tfile
16876         ln $DIR/$tfile $DIR/$tfile.lnk
16877         touch $DIR/$tfile.new
16878         mv $DIR/$tfile.new $DIR/$tfile
16879         local fid1=$($LFS path2fid $DIR/$tfile)
16880         local fid2=$($LFS path2fid $DIR/$tfile.lnk)
16881         local path1=$($LFS fid2path $FSNAME "$fid1")
16882         [ $tfile == $path1 ] || error "linkea inconsistent: $tfile $fid1 $path1"
16883         local path2=$($LFS fid2path $FSNAME "$fid2")
16884         [ $tfile.lnk == $path2 ] ||
16885                 error "linkea inconsistent: $tfile.lnk $fid2 $path2!"
16886         rm -f $DIR/$tfile*
16887 }
16888 run_test 238 "Verify linkea consistency"
16889
16890 test_239A() { # was test_239
16891         [ $MDS1_VERSION -lt $(version_code 2.5.60) ] &&
16892                 skip "Need MDS version at least 2.5.60"
16893
16894         local list=$(comma_list $(mdts_nodes))
16895
16896         mkdir -p $DIR/$tdir
16897         createmany -o $DIR/$tdir/f- 5000
16898         unlinkmany $DIR/$tdir/f- 5000
16899         [ $MDS1_VERSION -gt $(version_code 2.10.4) ] &&
16900                 do_nodes $list "lctl set_param -n osp.*.force_sync=1"
16901         changes=$(do_nodes $list "lctl get_param -n osp.*MDT*.sync_changes \
16902                         osp.*MDT*.sync_in_flight" | calc_sum)
16903         [ "$changes" -eq 0 ] || error "$changes not synced"
16904 }
16905 run_test 239A "osp_sync test"
16906
16907 test_239a() { #LU-5297
16908         remote_mds_nodsh && skip "remote MDS with nodsh"
16909
16910         touch $DIR/$tfile
16911         #define OBD_FAIL_OSP_CHECK_INVALID_REC     0x2100
16912         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2100
16913         chgrp $RUNAS_GID $DIR/$tfile
16914         wait_delete_completed
16915 }
16916 run_test 239a "process invalid osp sync record correctly"
16917
16918 test_239b() { #LU-5297
16919         remote_mds_nodsh && skip "remote MDS with nodsh"
16920
16921         touch $DIR/$tfile1
16922         #define OBD_FAIL_OSP_CHECK_ENOMEM     0x2101
16923         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2101
16924         chgrp $RUNAS_GID $DIR/$tfile1
16925         wait_delete_completed
16926         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
16927         touch $DIR/$tfile2
16928         chgrp $RUNAS_GID $DIR/$tfile2
16929         wait_delete_completed
16930 }
16931 run_test 239b "process osp sync record with ENOMEM error correctly"
16932
16933 test_240() {
16934         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
16935         remote_mds_nodsh && skip "remote MDS with nodsh"
16936
16937         mkdir -p $DIR/$tdir
16938
16939         $LFS mkdir -i 0 $DIR/$tdir/d0 ||
16940                 error "failed to mkdir $DIR/$tdir/d0 on MDT0"
16941         $LFS mkdir -i 1 $DIR/$tdir/d0/d1 ||
16942                 error "failed to mkdir $DIR/$tdir/d0/d1 on MDT1"
16943
16944         umount_client $MOUNT || error "umount failed"
16945         #define OBD_FAIL_TGT_DELAY_CONDITIONAL   0x713
16946         do_facet mds2 lctl set_param fail_loc=0x713 fail_val=1
16947         mount_client $MOUNT || error "failed to mount client"
16948
16949         echo "stat $DIR/$tdir/d0/d1, should not fail/ASSERT"
16950         stat $DIR/$tdir/d0/d1 || error "fail to stat $DIR/$tdir/d0/d1"
16951 }
16952 run_test 240 "race between ldlm enqueue and the connection RPC (no ASSERT)"
16953
16954 test_241_bio() {
16955         local count=$1
16956         local bsize=$2
16957
16958         for LOOP in $(seq $count); do
16959                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 2>/dev/null
16960                 cancel_lru_locks $OSC || true
16961         done
16962 }
16963
16964 test_241_dio() {
16965         local count=$1
16966         local bsize=$2
16967
16968         for LOOP in $(seq $1); do
16969                 dd if=$DIR/$tfile of=/dev/null bs=$bsize count=1 iflag=direct \
16970                         2>/dev/null
16971         done
16972 }
16973
16974 test_241a() { # was test_241
16975         local bsize=$PAGE_SIZE
16976
16977         (( bsize < 40960 )) && bsize=40960
16978         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16979         ls -la $DIR/$tfile
16980         cancel_lru_locks $OSC
16981         test_241_bio 1000 $bsize &
16982         PID=$!
16983         test_241_dio 1000 $bsize
16984         wait $PID
16985 }
16986 run_test 241a "bio vs dio"
16987
16988 test_241b() {
16989         local bsize=$PAGE_SIZE
16990
16991         (( bsize < 40960 )) && bsize=40960
16992         dd if=/dev/zero of=$DIR/$tfile count=1 bs=$bsize
16993         ls -la $DIR/$tfile
16994         test_241_dio 1000 $bsize &
16995         PID=$!
16996         test_241_dio 1000 $bsize
16997         wait $PID
16998 }
16999 run_test 241b "dio vs dio"
17000
17001 test_242() {
17002         remote_mds_nodsh && skip "remote MDS with nodsh"
17003
17004         mkdir -p $DIR/$tdir
17005         touch $DIR/$tdir/$tfile
17006
17007         #define OBD_FAIL_MDS_READPAGE_PACK      0x105
17008         do_facet mds1 lctl set_param fail_loc=0x105
17009         /bin/ls $DIR/$tdir && error "ls $DIR/$tdir should fail"
17010
17011         do_facet mds1 lctl set_param fail_loc=0
17012         /bin/ls $DIR/$tdir || error "ls $DIR/$tdir failed"
17013 }
17014 run_test 242 "mdt_readpage failure should not cause directory unreadable"
17015
17016 test_243()
17017 {
17018         test_mkdir $DIR/$tdir
17019         group_lock_test -d $DIR/$tdir || error "A group lock test failed"
17020 }
17021 run_test 243 "various group lock tests"
17022
17023 test_244a()
17024 {
17025         test_mkdir $DIR/$tdir
17026         dd if=/dev/zero of=$DIR/$tdir/$tfile bs=1M count=35
17027         sendfile_grouplock $DIR/$tdir/$tfile || \
17028                 error "sendfile+grouplock failed"
17029         rm -rf $DIR/$tdir
17030 }
17031 run_test 244a "sendfile with group lock tests"
17032
17033 test_244b()
17034 {
17035         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
17036
17037         local threads=50
17038         local size=$((1024*1024))
17039
17040         test_mkdir $DIR/$tdir
17041         for i in $(seq 1 $threads); do
17042                 local file=$DIR/$tdir/file_$((i / 10))
17043                 $MULTIOP $file OG1234w$size_$((i % 3))w$size_$((i % 4))g1234c &
17044                 local pids[$i]=$!
17045         done
17046         for i in $(seq 1 $threads); do
17047                 wait ${pids[$i]}
17048         done
17049 }
17050 run_test 244b "multi-threaded write with group lock"
17051
17052 test_245() {
17053         local flagname="multi_mod_rpcs"
17054         local connect_data_name="max_mod_rpcs"
17055         local out
17056
17057         # check if multiple modify RPCs flag is set
17058         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import |
17059                 grep "connect_flags:")
17060         echo "$out"
17061
17062         echo "$out" | grep -qw $flagname
17063         if [ $? -ne 0 ]; then
17064                 echo "connect flag $flagname is not set"
17065                 return
17066         fi
17067
17068         # check if multiple modify RPCs data is set
17069         out=$($LCTL get_param mdc.$FSNAME-MDT0000-*.import)
17070         echo "$out"
17071
17072         echo "$out" | grep -qw $connect_data_name ||
17073                 error "import should have connect data $connect_data_name"
17074 }
17075 run_test 245 "check mdc connection flag/data: multiple modify RPCs"
17076
17077 test_246() { # LU-7371
17078         remote_ost_nodsh && skip "remote OST with nodsh"
17079         [ $OST1_VERSION -lt $(version_code 2.7.62) ] &&
17080                 skip "Need OST version >= 2.7.62"
17081
17082         do_facet ost1 $LCTL set_param fail_val=4095
17083 #define OBD_FAIL_OST_READ_SIZE          0x234
17084         do_facet ost1 $LCTL set_param fail_loc=0x234
17085         $LFS setstripe $DIR/$tfile -i 0 -c 1
17086         dd if=/dev/zero of=$DIR/$tfile bs=4095 count=1 > /dev/null 2>&1
17087         cancel_lru_locks $FSNAME-OST0000
17088         dd if=$DIR/$tfile of=/dev/null bs=1048576 || error "Read failed"
17089 }
17090 run_test 246 "Read file of size 4095 should return right length"
17091
17092 cleanup_247() {
17093         local submount=$1
17094
17095         trap 0
17096         umount_client $submount
17097         rmdir $submount
17098 }
17099
17100 test_247a() {
17101         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17102                 grep -q subtree ||
17103                 skip_env "Fileset feature is not supported"
17104
17105         local submount=${MOUNT}_$tdir
17106
17107         mkdir $MOUNT/$tdir
17108         mkdir -p $submount || error "mkdir $submount failed"
17109         FILESET="$FILESET/$tdir" mount_client $submount ||
17110                 error "mount $submount failed"
17111         trap "cleanup_247 $submount" EXIT
17112         echo foo > $submount/$tfile || error "write $submount/$tfile failed"
17113         [ $(cat $MOUNT/$tdir/$tfile) = "foo" ] ||
17114                 error "read $MOUNT/$tdir/$tfile failed"
17115         cleanup_247 $submount
17116 }
17117 run_test 247a "mount subdir as fileset"
17118
17119 test_247b() {
17120         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17121                 skip_env "Fileset feature is not supported"
17122
17123         local submount=${MOUNT}_$tdir
17124
17125         rm -rf $MOUNT/$tdir
17126         mkdir -p $submount || error "mkdir $submount failed"
17127         SKIP_FILESET=1
17128         FILESET="$FILESET/$tdir" mount_client $submount &&
17129                 error "mount $submount should fail"
17130         rmdir $submount
17131 }
17132 run_test 247b "mount subdir that dose not exist"
17133
17134 test_247c() {
17135         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17136                 skip_env "Fileset feature is not supported"
17137
17138         local submount=${MOUNT}_$tdir
17139
17140         mkdir -p $MOUNT/$tdir/dir1
17141         mkdir -p $submount || error "mkdir $submount failed"
17142         trap "cleanup_247 $submount" EXIT
17143         FILESET="$FILESET/$tdir" mount_client $submount ||
17144                 error "mount $submount failed"
17145         local fid=$($LFS path2fid $MOUNT/)
17146         $LFS fid2path $submount $fid && error "fid2path should fail"
17147         cleanup_247 $submount
17148 }
17149 run_test 247c "running fid2path outside root"
17150
17151 test_247d() {
17152         lctl get_param -n mdc.$FSNAME-MDT0000*.import | grep -q subtree ||
17153                 skip "Fileset feature is not supported"
17154
17155         local submount=${MOUNT}_$tdir
17156
17157         mkdir -p $MOUNT/$tdir/dir1
17158         mkdir -p $submount || error "mkdir $submount failed"
17159         FILESET="$FILESET/$tdir" mount_client $submount ||
17160                 error "mount $submount failed"
17161         trap "cleanup_247 $submount" EXIT
17162         local fid=$($LFS path2fid $submount/dir1)
17163         $LFS fid2path $submount $fid || error "fid2path should succeed"
17164         cleanup_247 $submount
17165 }
17166 run_test 247d "running fid2path inside root"
17167
17168 # LU-8037
17169 test_247e() {
17170         lctl get_param -n mdc.$FSNAME-MDT0000*.import |
17171                 grep -q subtree ||
17172                 skip "Fileset feature is not supported"
17173
17174         local submount=${MOUNT}_$tdir
17175
17176         mkdir $MOUNT/$tdir
17177         mkdir -p $submount || error "mkdir $submount failed"
17178         FILESET="$FILESET/.." mount_client $submount &&
17179                 error "mount $submount should fail"
17180         rmdir $submount
17181 }
17182 run_test 247e "mount .. as fileset"
17183
17184 test_248() {
17185         local fast_read_sav=$($LCTL get_param -n llite.*.fast_read 2>/dev/null)
17186         [ -z "$fast_read_sav" ] && skip "no fast read support"
17187
17188         # create a large file for fast read verification
17189         dd if=/dev/zero of=$DIR/$tfile bs=1M count=128 > /dev/null 2>&1
17190
17191         # make sure the file is created correctly
17192         $CHECKSTAT -s $((128*1024*1024)) $DIR/$tfile ||
17193                 { rm -f $DIR/$tfile; skip "file creation error"; }
17194
17195         echo "Test 1: verify that fast read is 4 times faster on cache read"
17196
17197         # small read with fast read enabled
17198         $LCTL set_param -n llite.*.fast_read=1
17199         local t_fast=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17200                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17201                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17202         # small read with fast read disabled
17203         $LCTL set_param -n llite.*.fast_read=0
17204         local t_slow=$(dd if=$DIR/$tfile of=/dev/null bs=4k 2>&1 |
17205                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17206                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17207
17208         # verify that fast read is 4 times faster for cache read
17209         [ $(bc <<< "4 * $t_fast < $t_slow") -eq 1 ] ||
17210                 error_not_in_vm "fast read was not 4 times faster: " \
17211                            "$t_fast vs $t_slow"
17212
17213         echo "Test 2: verify the performance between big and small read"
17214         $LCTL set_param -n llite.*.fast_read=1
17215
17216         # 1k non-cache read
17217         cancel_lru_locks osc
17218         local t_1k=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17219                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17220                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17221
17222         # 1M non-cache read
17223         cancel_lru_locks osc
17224         local t_1m=$(dd if=$DIR/$tfile of=/dev/null bs=1k 2>&1 |
17225                 egrep -o '([[:digit:]\.\,e-]+) s' | cut -d's' -f1 |
17226                 sed -e 's/,/./' -e 's/[eE]+*/\*10\^/')
17227
17228         # verify that big IO is not 4 times faster than small IO
17229         [ $(bc <<< "4 * $t_1k >= $t_1m") -eq 1 ] ||
17230                 error_not_in_vm "bigger IO is way too fast: $t_1k vs $t_1m"
17231
17232         $LCTL set_param -n llite.*.fast_read=$fast_read_sav
17233         rm -f $DIR/$tfile
17234 }
17235 run_test 248 "fast read verification"
17236
17237 test_249() { # LU-7890
17238         [ $MDS1_VERSION -lt $(version_code 2.8.53) ] &&
17239                 skip "Need at least version 2.8.54"
17240
17241         rm -f $DIR/$tfile
17242         $LFS setstripe -c 1 $DIR/$tfile
17243         # Offset 2T == 4k * 512M
17244         dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 seek=512M ||
17245                 error "dd to 2T offset failed"
17246 }
17247 run_test 249 "Write above 2T file size"
17248
17249 test_250() {
17250         [ "$(facet_fstype ost$(($($LFS getstripe -i $DIR/$tfile) + 1)))" = "zfs" ] \
17251          && skip "no 16TB file size limit on ZFS"
17252
17253         $LFS setstripe -c 1 $DIR/$tfile
17254         # ldiskfs extent file size limit is (16TB - 4KB - 1) bytes
17255         local size=$((16 * 1024 * 1024 * 1024 * 1024 - 4096 - 1))
17256         $TRUNCATE $DIR/$tfile $size || error "truncate $tfile to $size failed"
17257         dd if=/dev/zero of=$DIR/$tfile bs=10 count=1 oflag=append \
17258                 conv=notrunc,fsync && error "append succeeded"
17259         return 0
17260 }
17261 run_test 250 "Write above 16T limit"
17262
17263 test_251() {
17264         $LFS setstripe -c -1 -S 1048576 $DIR/$tfile
17265
17266         #define OBD_FAIL_LLITE_LOST_LAYOUT 0x1407
17267         #Skip once - writing the first stripe will succeed
17268         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17269         $MULTIOP $DIR/$tfile o:O_RDWR:w2097152c 2>&1 | grep -q "short write" &&
17270                 error "short write happened"
17271
17272         $LCTL set_param fail_loc=0xa0001407 fail_val=1
17273         $MULTIOP $DIR/$tfile or2097152c 2>&1 | grep -q "short read" &&
17274                 error "short read happened"
17275
17276         rm -f $DIR/$tfile
17277 }
17278 run_test 251 "Handling short read and write correctly"
17279
17280 test_252() {
17281         remote_mds_nodsh && skip "remote MDS with nodsh"
17282         remote_ost_nodsh && skip "remote OST with nodsh"
17283         if [ "$ost1_FSTYPE" != ldiskfs ] || [ "$mds1_FSTYPE" != ldiskfs ]; then
17284                 skip_env "ldiskfs only test"
17285         fi
17286
17287         local tgt
17288         local dev
17289         local out
17290         local uuid
17291         local num
17292         local gen
17293
17294         # check lr_reader on OST0000
17295         tgt=ost1
17296         dev=$(facet_device $tgt)
17297         out=$(do_facet $tgt $LR_READER $dev)
17298         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17299         echo "$out"
17300         uuid=$(echo "$out" | grep -i uuid | awk '{ print $2 }')
17301         [ "$uuid" == "$(ostuuid_from_index 0)" ] ||
17302                 error "Invalid uuid returned by $LR_READER on target $tgt"
17303         echo -e "uuid returned by $LR_READER is '$uuid'\n"
17304
17305         # check lr_reader -c on MDT0000
17306         tgt=mds1
17307         dev=$(facet_device $tgt)
17308         if ! do_facet $tgt $LR_READER -h | grep -q OPTIONS; then
17309                 skip "$LR_READER does not support additional options"
17310         fi
17311         out=$(do_facet $tgt $LR_READER -c $dev)
17312         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17313         echo "$out"
17314         num=$(echo "$out" | grep -c "mdtlov")
17315         [ "$num" -eq $((MDSCOUNT - 1)) ] ||
17316                 error "Invalid number of mdtlov clients returned by $LR_READER"
17317         echo -e "Number of mdtlov clients returned by $LR_READER is '$num'\n"
17318
17319         # check lr_reader -cr on MDT0000
17320         out=$(do_facet $tgt $LR_READER -cr $dev)
17321         [ $? -eq 0 ] || error "$LR_READER failed on target $tgt device $dev"
17322         echo "$out"
17323         echo "$out" | grep -q "^reply_data:$" ||
17324                 error "$LR_READER should have returned 'reply_data' section"
17325         num=$(echo "$out" | grep -c "client_generation")
17326         echo -e "Number of reply data returned by $LR_READER is '$num'\n"
17327 }
17328 run_test 252 "check lr_reader tool"
17329
17330 test_253() {
17331         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17332         remote_mds_nodsh && skip "remote MDS with nodsh"
17333         remote_mgs_nodsh && skip "remote MGS with nodsh"
17334
17335         local ostidx=0
17336         local rc=0
17337         local ost_name=$(ostname_from_index $ostidx)
17338
17339         # on the mdt's osc
17340         local mdtosc_proc1=$(get_mdtosc_proc_path $SINGLEMDS $ost_name)
17341         do_facet $SINGLEMDS $LCTL get_param -n \
17342                 osp.$mdtosc_proc1.reserved_mb_high ||
17343                 skip  "remote MDS does not support reserved_mb_high"
17344
17345         rm -rf $DIR/$tdir
17346         wait_mds_ost_sync
17347         wait_delete_completed
17348         mkdir $DIR/$tdir
17349
17350         if ! combined_mgs_mds ; then
17351                 mount_mgs_client
17352         fi
17353         pool_add $TESTNAME || error "Pool creation failed"
17354         pool_add_targets $TESTNAME 0 || error "Pool add targets failed"
17355
17356         $LFS setstripe $DIR/$tdir -i $ostidx -c 1 -p $FSNAME.$TESTNAME ||
17357                 error "Setstripe failed"
17358
17359         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M count=10
17360
17361         local wms=$(ost_watermarks_set_enospc $tfile $ostidx |
17362                     grep "watermarks")
17363         stack_trap "ost_watermarks_clear_enospc $tfile $ostidx $wms" EXIT
17364
17365         local oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17366                         osp.$mdtosc_proc1.prealloc_status)
17367         echo "prealloc_status $oa_status"
17368
17369         dd if=/dev/zero of=$DIR/$tdir/$tfile.1 bs=1M count=1 &&
17370                 error "File creation should fail"
17371
17372         #object allocation was stopped, but we still able to append files
17373         dd if=/dev/zero of=$DIR/$tdir/$tfile.0 bs=1M seek=6 count=5 \
17374                 oflag=append || error "Append failed"
17375
17376         rm -f $DIR/$tdir/$tfile.0
17377
17378         # For this test, we want to delete the files we created to go out of
17379         # space but leave the watermark, so we remain nearly out of space
17380         ost_watermarks_enospc_delete_files $tfile $ostidx
17381
17382         wait_delete_completed
17383
17384         sleep_maxage
17385
17386         for i in $(seq 10 12); do
17387                 dd if=/dev/zero of=$DIR/$tdir/$tfile.$i bs=1M count=1 \
17388                         2>/dev/null || error "File creation failed after rm"
17389         done
17390
17391         oa_status=$(do_facet $SINGLEMDS $LCTL get_param -n \
17392                         osp.$mdtosc_proc1.prealloc_status)
17393         echo "prealloc_status $oa_status"
17394
17395         if (( oa_status != 0 )); then
17396                 error "Object allocation still disable after rm"
17397         fi
17398
17399         if ! combined_mgs_mds ; then
17400                 umount_mgs_client
17401         fi
17402 }
17403 run_test 253 "Check object allocation limit"
17404
17405 test_254() {
17406         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17407         remote_mds_nodsh && skip "remote MDS with nodsh"
17408         do_facet $SINGLEMDS $LCTL get_param -n mdd.$MDT0.changelog_size ||
17409                 skip "MDS does not support changelog_size"
17410
17411         local cl_user
17412         local MDT0=$(facet_svc $SINGLEMDS)
17413
17414         changelog_register || error "changelog_register failed"
17415
17416         changelog_clear 0 || error "changelog_clear failed"
17417
17418         local size1=$(do_facet $SINGLEMDS \
17419                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17420         echo "Changelog size $size1"
17421
17422         rm -rf $DIR/$tdir
17423         $LFS mkdir -i 0 $DIR/$tdir
17424         # change something
17425         mkdir -p $DIR/$tdir/pics/2008/zachy
17426         touch $DIR/$tdir/pics/2008/zachy/timestamp
17427         cp /etc/hosts $DIR/$tdir/pics/2008/zachy/pic1.jpg
17428         mv $DIR/$tdir/pics/2008/zachy $DIR/$tdir/pics/zach
17429         ln $DIR/$tdir/pics/zach/pic1.jpg $DIR/$tdir/pics/2008/portland.jpg
17430         ln -s $DIR/$tdir/pics/2008/portland.jpg $DIR/$tdir/pics/desktop.jpg
17431         rm $DIR/$tdir/pics/desktop.jpg
17432
17433         local size2=$(do_facet $SINGLEMDS \
17434                       $LCTL get_param -n mdd.$MDT0.changelog_size)
17435         echo "Changelog size after work $size2"
17436
17437         (( $size2 > $size1 )) ||
17438                 error "new Changelog size=$size2 less than old size=$size1"
17439 }
17440 run_test 254 "Check changelog size"
17441
17442 ladvise_no_type()
17443 {
17444         local type=$1
17445         local file=$2
17446
17447         lfs ladvise -a invalid $file 2>&1 | grep "Valid types" |
17448                 awk -F: '{print $2}' | grep $type > /dev/null
17449         if [ $? -ne 0 ]; then
17450                 return 0
17451         fi
17452         return 1
17453 }
17454
17455 ladvise_no_ioctl()
17456 {
17457         local file=$1
17458
17459         lfs ladvise -a willread $file > /dev/null 2>&1
17460         if [ $? -eq 0 ]; then
17461                 return 1
17462         fi
17463
17464         lfs ladvise -a willread $file 2>&1 |
17465                 grep "Inappropriate ioctl for device" > /dev/null
17466         if [ $? -eq 0 ]; then
17467                 return 0
17468         fi
17469         return 1
17470 }
17471
17472 percent() {
17473         bc <<<"scale=2; ($1 - $2) * 100 / $2"
17474 }
17475
17476 # run a random read IO workload
17477 # usage: random_read_iops <filename> <filesize> <iosize>
17478 random_read_iops() {
17479         local file=$1
17480         local fsize=$2
17481         local iosize=${3:-4096}
17482
17483         $READS -f $file -s $fsize -b $iosize -n $((fsize / iosize)) -t 60 |
17484                 sed -e '/^$/d' -e 's#.*s, ##' -e 's#MB/s##'
17485 }
17486
17487 drop_file_oss_cache() {
17488         local file="$1"
17489         local nodes="$2"
17490
17491         $LFS ladvise -a dontneed $file 2>/dev/null ||
17492                 do_nodes $nodes "echo 3 > /proc/sys/vm/drop_caches"
17493 }
17494
17495 ladvise_willread_performance()
17496 {
17497         local repeat=10
17498         local average_origin=0
17499         local average_cache=0
17500         local average_ladvise=0
17501
17502         for ((i = 1; i <= $repeat; i++)); do
17503                 echo "Iter $i/$repeat: reading without willread hint"
17504                 cancel_lru_locks osc
17505                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17506                 local speed_origin=$(random_read_iops $DIR/$tfile $size)
17507                 echo "Iter $i/$repeat: uncached speed: $speed_origin"
17508                 average_origin=$(bc <<<"$average_origin + $speed_origin")
17509
17510                 cancel_lru_locks osc
17511                 local speed_cache=$(random_read_iops $DIR/$tfile $size)
17512                 echo "Iter $i/$repeat: OSS cache speed: $speed_cache"
17513                 average_cache=$(bc <<<"$average_cache + $speed_cache")
17514
17515                 cancel_lru_locks osc
17516                 drop_file_oss_cache $DIR/$tfile $(comma_list $(osts_nodes))
17517                 $LFS ladvise -a willread $DIR/$tfile || error "ladvise failed"
17518                 local speed_ladvise=$(random_read_iops $DIR/$tfile $size)
17519                 echo "Iter $i/$repeat: ladvise speed: $speed_ladvise"
17520                 average_ladvise=$(bc <<<"$average_ladvise + $speed_ladvise")
17521         done
17522         average_origin=$(bc <<<"scale=2; $average_origin / $repeat")
17523         average_cache=$(bc <<<"scale=2; $average_cache / $repeat")
17524         average_ladvise=$(bc <<<"scale=2; $average_ladvise / $repeat")
17525
17526         speedup_cache=$(percent $average_cache $average_origin)
17527         speedup_ladvise=$(percent $average_ladvise $average_origin)
17528
17529         echo "Average uncached read: $average_origin"
17530         echo "Average speedup with OSS cached read: " \
17531                 "$average_cache = +$speedup_cache%"
17532         echo "Average speedup with ladvise willread: " \
17533                 "$average_ladvise = +$speedup_ladvise%"
17534
17535         local lowest_speedup=20
17536         if [ ${average_cache%.*} -lt $lowest_speedup ]; then
17537                 echo "Speedup with OSS cached read less than $lowest_speedup%," \
17538                         "got $average_cache%. Skipping ladvise willread check."
17539                 return 0
17540         fi
17541
17542         # the test won't work on ZFS until it supports 'ladvise dontneed', but
17543         # it is still good to run until then to exercise 'ladvise willread'
17544         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17545                 [ "$ost1_FSTYPE" = "zfs" ] &&
17546                 echo "osd-zfs does not support dontneed or drop_caches" &&
17547                 return 0
17548
17549         lowest_speedup=$(bc <<<"scale=2; $average_cache / 2")
17550         [ ${average_ladvise%.*} -gt $lowest_speedup ] ||
17551                 error_not_in_vm "Speedup with willread is less than " \
17552                         "$lowest_speedup%, got $average_ladvise%"
17553 }
17554
17555 test_255a() {
17556         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17557                 skip "lustre < 2.8.54 does not support ladvise "
17558         remote_ost_nodsh && skip "remote OST with nodsh"
17559
17560         lfs setstripe -c -1 -i 0 $DIR/$tfile || error "$tfile failed"
17561
17562         ladvise_no_type willread $DIR/$tfile &&
17563                 skip "willread ladvise is not supported"
17564
17565         ladvise_no_ioctl $DIR/$tfile &&
17566                 skip "ladvise ioctl is not supported"
17567
17568         local size_mb=100
17569         local size=$((size_mb * 1048576))
17570         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17571                 error "dd to $DIR/$tfile failed"
17572
17573         lfs ladvise -a willread $DIR/$tfile ||
17574                 error "Ladvise failed with no range argument"
17575
17576         lfs ladvise -a willread -s 0 $DIR/$tfile ||
17577                 error "Ladvise failed with no -l or -e argument"
17578
17579         lfs ladvise -a willread -e 1 $DIR/$tfile ||
17580                 error "Ladvise failed with only -e argument"
17581
17582         lfs ladvise -a willread -l 1 $DIR/$tfile ||
17583                 error "Ladvise failed with only -l argument"
17584
17585         lfs ladvise -a willread -s 2 -e 1 $DIR/$tfile &&
17586                 error "End offset should not be smaller than start offset"
17587
17588         lfs ladvise -a willread -s 2 -e 2 $DIR/$tfile &&
17589                 error "End offset should not be equal to start offset"
17590
17591         lfs ladvise -a willread -s $size -l 1 $DIR/$tfile ||
17592                 error "Ladvise failed with overflowing -s argument"
17593
17594         lfs ladvise -a willread -s 1 -e $((size + 1)) $DIR/$tfile ||
17595                 error "Ladvise failed with overflowing -e argument"
17596
17597         lfs ladvise -a willread -s 1 -l $size $DIR/$tfile ||
17598                 error "Ladvise failed with overflowing -l argument"
17599
17600         lfs ladvise -a willread -l 1 -e 2 $DIR/$tfile &&
17601                 error "Ladvise succeeded with conflicting -l and -e arguments"
17602
17603         echo "Synchronous ladvise should wait"
17604         local delay=4
17605 #define OBD_FAIL_OST_LADVISE_PAUSE       0x237
17606         do_nodes $(comma_list $(osts_nodes)) \
17607                 $LCTL set_param fail_val=$delay fail_loc=0x237
17608
17609         local start_ts=$SECONDS
17610         lfs ladvise -a willread $DIR/$tfile ||
17611                 error "Ladvise failed with no range argument"
17612         local end_ts=$SECONDS
17613         local inteval_ts=$((end_ts - start_ts))
17614
17615         if [ $inteval_ts -lt $(($delay - 1)) ]; then
17616                 error "Synchronous advice didn't wait reply"
17617         fi
17618
17619         echo "Asynchronous ladvise shouldn't wait"
17620         local start_ts=$SECONDS
17621         lfs ladvise -a willread -b $DIR/$tfile ||
17622                 error "Ladvise failed with no range argument"
17623         local end_ts=$SECONDS
17624         local inteval_ts=$((end_ts - start_ts))
17625
17626         if [ $inteval_ts -gt $(($delay / 2)) ]; then
17627                 error "Asynchronous advice blocked"
17628         fi
17629
17630         do_nodes $(comma_list $(osts_nodes)) $LCTL set_param fail_loc=0
17631         ladvise_willread_performance
17632 }
17633 run_test 255a "check 'lfs ladvise -a willread'"
17634
17635 facet_meminfo() {
17636         local facet=$1
17637         local info=$2
17638
17639         do_facet $facet "cat /proc/meminfo | grep ^${info}:" | awk '{print $2}'
17640 }
17641
17642 test_255b() {
17643         [ $OST1_VERSION -lt $(version_code 2.8.54) ] &&
17644                 skip "lustre < 2.8.54 does not support ladvise "
17645         remote_ost_nodsh && skip "remote OST with nodsh"
17646
17647         lfs setstripe -c 1 -i 0 $DIR/$tfile
17648
17649         ladvise_no_type dontneed $DIR/$tfile &&
17650                 skip "dontneed ladvise is not supported"
17651
17652         ladvise_no_ioctl $DIR/$tfile &&
17653                 skip "ladvise ioctl is not supported"
17654
17655         ! $LFS ladvise -a dontneed $DIR/$tfile &&
17656                 [ "$ost1_FSTYPE" = "zfs" ] &&
17657                 skip "zfs-osd does not support 'ladvise dontneed'"
17658
17659         local size_mb=100
17660         local size=$((size_mb * 1048576))
17661         # In order to prevent disturbance of other processes, only check 3/4
17662         # of the memory usage
17663         local kibibytes=$((size_mb * 1024 * 3 / 4))
17664
17665         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=$size_mb ||
17666                 error "dd to $DIR/$tfile failed"
17667
17668         #force write to complete before dropping OST cache & checking memory
17669         sync
17670
17671         local total=$(facet_meminfo ost1 MemTotal)
17672         echo "Total memory: $total KiB"
17673
17674         do_facet ost1 "sync && echo 3 > /proc/sys/vm/drop_caches"
17675         local before_read=$(facet_meminfo ost1 Cached)
17676         echo "Cache used before read: $before_read KiB"
17677
17678         lfs ladvise -a willread $DIR/$tfile ||
17679                 error "Ladvise willread failed"
17680         local after_read=$(facet_meminfo ost1 Cached)
17681         echo "Cache used after read: $after_read KiB"
17682
17683         lfs ladvise -a dontneed $DIR/$tfile ||
17684                 error "Ladvise dontneed again failed"
17685         local no_read=$(facet_meminfo ost1 Cached)
17686         echo "Cache used after dontneed ladvise: $no_read KiB"
17687
17688         if [ $total -lt $((before_read + kibibytes)) ]; then
17689                 echo "Memory is too small, abort checking"
17690                 return 0
17691         fi
17692
17693         if [ $((before_read + kibibytes)) -gt $after_read ]; then
17694                 error "Ladvise willread should use more memory" \
17695                         "than $kibibytes KiB"
17696         fi
17697
17698         if [ $((no_read + kibibytes)) -gt $after_read ]; then
17699                 error "Ladvise dontneed should release more memory" \
17700                         "than $kibibytes KiB"
17701         fi
17702 }
17703 run_test 255b "check 'lfs ladvise -a dontneed'"
17704
17705 test_255c() {
17706         [ $OST1_VERSION -lt $(version_code 2.10.50) ] &&
17707                 skip "lustre < 2.10.50 does not support lockahead"
17708
17709         local count
17710         local new_count
17711         local difference
17712         local i
17713         local rc
17714
17715         test_mkdir -p $DIR/$tdir
17716         $LFS setstripe -i 0 -c 1 $DIR/$tdir
17717
17718         #test 10 returns only success/failure
17719         i=10
17720         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17721         rc=$?
17722         if [ $rc -eq 255 ]; then
17723                 error "Ladvise test${i} failed, ${rc}"
17724         fi
17725
17726         #test 11 counts lock enqueue requests, all others count new locks
17727         i=11
17728         count=$(do_facet ost1 \
17729                 $LCTL get_param -n ost.OSS.ost.stats)
17730         count=$(echo "$count" | grep ldlm_extent_enqueue | awk '{ print $2 }')
17731
17732         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17733         rc=$?
17734         if [ $rc -eq 255 ]; then
17735                 error "Ladvise test${i} failed, ${rc}"
17736         fi
17737
17738         new_count=$(do_facet ost1 \
17739                 $LCTL get_param -n ost.OSS.ost.stats)
17740         new_count=$(echo "$new_count" | grep ldlm_extent_enqueue | \
17741                    awk '{ print $2 }')
17742
17743         difference="$((new_count - count))"
17744         if [ $difference -ne $rc ]; then
17745                 error "Ladvise test${i}, bad enqueue count, returned " \
17746                       "${rc}, actual ${difference}"
17747         fi
17748
17749         for i in $(seq 12 21); do
17750                 # If we do not do this, we run the risk of having too many
17751                 # locks and starting lock cancellation while we are checking
17752                 # lock counts.
17753                 cancel_lru_locks osc
17754
17755                 count=$($LCTL get_param -n \
17756                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17757
17758                 lockahead_test -d $DIR/$tdir -t $i -f $tfile
17759                 rc=$?
17760                 if [ $rc -eq 255 ]; then
17761                         error "Ladvise test ${i} failed, ${rc}"
17762                 fi
17763
17764                 new_count=$($LCTL get_param -n \
17765                        ldlm.namespaces.$FSNAME-OST0000*osc-[-0-9a-f]*.lock_unused_count)
17766                 difference="$((new_count - count))"
17767
17768                 # Test 15 output is divided by 100 to map down to valid return
17769                 if [ $i -eq 15 ]; then
17770                         rc="$((rc * 100))"
17771                 fi
17772
17773                 if [ $difference -ne $rc ]; then
17774                         error "Ladvise test ${i}, bad lock count, returned " \
17775                               "${rc}, actual ${difference}"
17776                 fi
17777         done
17778
17779         #test 22 returns only success/failure
17780         i=22
17781         lockahead_test -d $DIR/$tdir -t $i -f $tfile
17782         rc=$?
17783         if [ $rc -eq 255 ]; then
17784                 error "Ladvise test${i} failed, ${rc}"
17785         fi
17786 }
17787 run_test 255c "suite of ladvise lockahead tests"
17788
17789 test_256() {
17790         [ $PARALLEL == "yes" ] && skip "skip parallel run"
17791         remote_mds_nodsh && skip "remote MDS with nodsh"
17792         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17793         changelog_users $SINGLEMDS | grep "^cl" &&
17794                 skip "active changelog user"
17795
17796         local cl_user
17797         local cat_sl
17798         local mdt_dev
17799
17800         mdt_dev=$(mdsdevname 1)
17801         echo $mdt_dev
17802
17803         changelog_register || error "changelog_register failed"
17804
17805         rm -rf $DIR/$tdir
17806         mkdir -p $DIR/$tdir
17807
17808         changelog_clear 0 || error "changelog_clear failed"
17809
17810         # change something
17811         touch $DIR/$tdir/{1..10}
17812
17813         # stop the MDT
17814         stop $SINGLEMDS || error "Fail to stop MDT"
17815
17816         # remount the MDT
17817
17818         start $SINGLEMDS $mdt_dev $MDS_MOUNT_OPTS || error "Fail to start MDT"
17819
17820         #after mount new plainllog is used
17821         touch $DIR/$tdir/{11..19}
17822         local tmpfile="$(mktemp --tmpdir -u $tfile.XXXXXX)"
17823         stack_trap "rm -f $tmpfile"
17824         cat_sl=$(do_facet $SINGLEMDS "sync; \
17825                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17826                  llog_reader $tmpfile | grep -c type=1064553b")
17827         do_facet $SINGLEMDS llog_reader $tmpfile
17828
17829         [ $cat_sl != 2 ] && error "Changelog catalog has $cat_sl != 2 slots"
17830
17831         changelog_clear 0 || error "changelog_clear failed"
17832
17833         cat_sl=$(do_facet $SINGLEMDS "sync; \
17834                  $DEBUGFS -c -R 'dump changelog_catalog $tmpfile' $mdt_dev; \
17835                  llog_reader $tmpfile | grep -c type=1064553b")
17836
17837         if (( cat_sl == 2 )); then
17838                 error "Empty plain llog was not deleted from changelog catalog"
17839         elif (( cat_sl != 1 )); then
17840                 error "Active plain llog shouldn't be deleted from catalog"
17841         fi
17842 }
17843 run_test 256 "Check llog delete for empty and not full state"
17844
17845 test_257() {
17846         remote_mds_nodsh && skip "remote MDS with nodsh"
17847         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
17848                 skip "Need MDS version at least 2.8.55"
17849
17850         test_mkdir $DIR/$tdir
17851
17852         setfattr -n trusted.name1 -v value1 $DIR/$tdir ||
17853                 error "setfattr -n trusted.name1=value1 $DIR/$tdir failed"
17854         stat $DIR/$tdir
17855
17856 #define OBD_FAIL_MDS_XATTR_REP                  0x161
17857         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
17858         local facet=mds$((mdtidx + 1))
17859         set_nodes_failloc $(facet_active_host $facet) 0x80000161
17860         getfattr -n trusted.name1 $DIR/$tdir 2> /dev/null
17861
17862         stop $facet || error "stop MDS failed"
17863         start $facet $(mdsdevname $((mdtidx + 1))) $MDS_MOUNT_OPTS ||
17864                 error "start MDS fail"
17865         wait_recovery_complete $facet
17866 }
17867 run_test 257 "xattr locks are not lost"
17868
17869 # Verify we take the i_mutex when security requires it
17870 test_258a() {
17871 #define OBD_FAIL_IMUTEX_SEC 0x141c
17872         $LCTL set_param fail_loc=0x141c
17873         touch $DIR/$tfile
17874         chmod u+s $DIR/$tfile
17875         chmod a+rwx $DIR/$tfile
17876         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17877         RC=$?
17878         if [ $RC -ne 0 ]; then
17879                 error "error, failed to take i_mutex, rc=$?"
17880         fi
17881         rm -f $DIR/$tfile
17882 }
17883 run_test 258a "verify i_mutex security behavior when suid attributes is set"
17884
17885 # Verify we do NOT take the i_mutex in the normal case
17886 test_258b() {
17887 #define OBD_FAIL_IMUTEX_NOSEC 0x141d
17888         $LCTL set_param fail_loc=0x141d
17889         touch $DIR/$tfile
17890         chmod a+rwx $DIR
17891         chmod a+rw $DIR/$tfile
17892         $RUNAS dd if=/dev/zero of=$DIR/$tfile bs=4k count=1 oflag=append
17893         RC=$?
17894         if [ $RC -ne 0 ]; then
17895                 error "error, took i_mutex unnecessarily, rc=$?"
17896         fi
17897         rm -f $DIR/$tfile
17898
17899 }
17900 run_test 258b "verify i_mutex security behavior"
17901
17902 test_259() {
17903         local file=$DIR/$tfile
17904         local before
17905         local after
17906
17907         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip "ldiskfs only test"
17908
17909         stack_trap "rm -f $file" EXIT
17910
17911         wait_delete_completed
17912         before=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17913         echo "before: $before"
17914
17915         $LFS setstripe -i 0 -c 1 $file
17916         dd if=/dev/zero of=$file bs=1M count=10 || error "couldn't write"
17917         sync_all_data
17918         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17919         echo "after write: $after"
17920
17921 #define OBD_FAIL_OSD_FAIL_AT_TRUNCATE          0x2301
17922         do_facet ost1 $LCTL set_param fail_loc=0x2301
17923         $TRUNCATE $file 0
17924         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17925         echo "after truncate: $after"
17926
17927         stop ost1
17928         do_facet ost1 $LCTL set_param fail_loc=0
17929         start ost1 $(ostdevname 1) $OST_MOUNT_OPTS || error "cannot start ost1"
17930         sleep 2
17931         after=$(do_facet ost1 "$LCTL get_param -n osd-*.*OST0000.kbytesfree")
17932         echo "after restart: $after"
17933         [ $((after - before)) -ge $(fs_log_size ost1) ] &&
17934                 error "missing truncate?"
17935
17936         return 0
17937 }
17938 run_test 259 "crash at delayed truncate"
17939
17940 test_260() {
17941 #define OBD_FAIL_MDC_CLOSE               0x806
17942         $LCTL set_param fail_loc=0x80000806
17943         touch $DIR/$tfile
17944
17945 }
17946 run_test 260 "Check mdc_close fail"
17947
17948 ### Data-on-MDT sanity tests ###
17949 test_270a() {
17950         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
17951                 skip "Need MDS version at least 2.10.55 for DoM"
17952
17953         # create DoM file
17954         local dom=$DIR/$tdir/dom_file
17955         local tmp=$DIR/$tdir/tmp_file
17956
17957         mkdir -p $DIR/$tdir
17958
17959         # basic checks for DoM component creation
17960         $LFS setstripe -E 1024K -E 2048K -L mdt $dom 2>/dev/null &&
17961                 error "Can set MDT layout to non-first entry"
17962
17963         $LFS setstripe -E 1024K -L mdt -E 2048K -L mdt $dom 2>/dev/null &&
17964                 error "Can define multiple entries as MDT layout"
17965
17966         $LFS setstripe -E 1M -L mdt $dom || error "Can't create DoM layout"
17967
17968         [ $($LFS getstripe -L $dom) == "mdt" ] || error "bad pattern"
17969         [ $($LFS getstripe -c $dom) == 0 ] || error "bad stripe count"
17970         [ $($LFS getstripe -S $dom) == 1048576 ] || error "bad stripe size"
17971
17972         local mdtidx=$($LFS getstripe -m $dom)
17973         local mdtname=MDT$(printf %04x $mdtidx)
17974         local facet=mds$((mdtidx + 1))
17975         local space_check=1
17976
17977         # Skip free space checks with ZFS
17978         [ "$(facet_fstype $facet)" == "zfs" ] && space_check=0
17979
17980         # write
17981         sync
17982         local size_tmp=$((65536 * 3))
17983         local mdtfree1=$(do_facet $facet \
17984                          lctl get_param -n osd*.*$mdtname.kbytesfree)
17985
17986         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
17987         # check also direct IO along write
17988         # IO size must be a multiple of PAGE_SIZE on all platforms (ARM=64KB)
17989         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
17990         sync
17991         cmp $tmp $dom || error "file data is different"
17992         [ $(stat -c%s $dom) == $size_tmp ] ||
17993                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
17994         if [ $space_check == 1 ]; then
17995                 local mdtfree2=$(do_facet $facet \
17996                                  lctl get_param -n osd*.*$mdtname.kbytesfree)
17997
17998                 # increase in usage from by $size_tmp
17999                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18000                         error "MDT free space wrong after write: " \
18001                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18002         fi
18003
18004         # truncate
18005         local size_dom=10000
18006
18007         $TRUNCATE $dom $size_dom
18008         [ $(stat -c%s $dom) == $size_dom ] ||
18009                 error "bad size after truncate: $(stat -c%s $dom) != $size_dom"
18010         if [ $space_check == 1 ]; then
18011                 mdtfree1=$(do_facet $facet \
18012                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18013                 # decrease in usage from $size_tmp to new $size_dom
18014                 [ $(($mdtfree1 - $mdtfree2)) -ge \
18015                   $(((size_tmp - size_dom) / 1024)) ] ||
18016                         error "MDT free space is wrong after truncate: " \
18017                               "$mdtfree1 >= $mdtfree2 + ($size_tmp - $size_dom) / 1024"
18018         fi
18019
18020         # append
18021         cat $tmp >> $dom
18022         sync
18023         size_dom=$((size_dom + size_tmp))
18024         [ $(stat -c%s $dom) == $size_dom ] ||
18025                 error "bad size after append: $(stat -c%s $dom) != $size_dom"
18026         if [ $space_check == 1 ]; then
18027                 mdtfree2=$(do_facet $facet \
18028                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18029                 # increase in usage by $size_tmp from previous
18030                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_tmp / 1024)) ] ||
18031                         error "MDT free space is wrong after append: " \
18032                               "$mdtfree1 >= $mdtfree2 + $size_tmp/1024"
18033         fi
18034
18035         # delete
18036         rm $dom
18037         if [ $space_check == 1 ]; then
18038                 mdtfree1=$(do_facet $facet \
18039                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18040                 # decrease in usage by $size_dom from previous
18041                 [ $(($mdtfree1 - $mdtfree2)) -ge $((size_dom / 1024)) ] ||
18042                         error "MDT free space is wrong after removal: " \
18043                               "$mdtfree1 >= $mdtfree2 + $size_dom/1024"
18044         fi
18045
18046         # combined striping
18047         $LFS setstripe -E 1024K -L mdt -E EOF $dom ||
18048                 error "Can't create DoM + OST striping"
18049
18050         size_tmp=2031616 # must be a multiple of PAGE_SIZE=65536 on ARM
18051         dd if=/dev/urandom of=$tmp bs=1024 count=$((size_tmp / 1024))
18052         # check also direct IO along write
18053         dd if=$tmp of=$dom bs=65536 count=$((size_tmp / 65536)) oflag=direct
18054         sync
18055         cmp $tmp $dom || error "file data is different"
18056         [ $(stat -c%s $dom) == $size_tmp ] ||
18057                 error "bad size after write: $(stat -c%s $dom) != $size_tmp"
18058         rm $dom $tmp
18059
18060         return 0
18061 }
18062 run_test 270a "DoM: basic functionality tests"
18063
18064 test_270b() {
18065         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18066                 skip "Need MDS version at least 2.10.55"
18067
18068         local dom=$DIR/$tdir/dom_file
18069         local max_size=1048576
18070
18071         mkdir -p $DIR/$tdir
18072         $LFS setstripe -E $max_size -L mdt $dom
18073
18074         # truncate over the limit
18075         $TRUNCATE $dom $(($max_size + 1)) &&
18076                 error "successful truncate over the maximum size"
18077         # write over the limit
18078         dd if=/dev/zero of=$dom bs=$max_size seek=1 count=1 &&
18079                 error "successful write over the maximum size"
18080         # append over the limit
18081         dd if=/dev/zero of=$dom bs=$(($max_size - 3)) count=1
18082         echo "12345" >> $dom && error "successful append over the maximum size"
18083         rm $dom
18084
18085         return 0
18086 }
18087 run_test 270b "DoM: maximum size overflow checks for DoM-only file"
18088
18089 test_270c() {
18090         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18091                 skip "Need MDS version at least 2.10.55"
18092
18093         mkdir -p $DIR/$tdir
18094         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18095
18096         # check files inherit DoM EA
18097         touch $DIR/$tdir/first
18098         [ $($LFS getstripe -L $DIR/$tdir/first) == "mdt" ] ||
18099                 error "bad pattern"
18100         [ $($LFS getstripe -c $DIR/$tdir/first) == 0 ] ||
18101                 error "bad stripe count"
18102         [ $($LFS getstripe -S $DIR/$tdir/first) == 1048576 ] ||
18103                 error "bad stripe size"
18104
18105         # check directory inherits DoM EA and uses it as default
18106         mkdir $DIR/$tdir/subdir
18107         touch $DIR/$tdir/subdir/second
18108         [ $($LFS getstripe -L $DIR/$tdir/subdir/second) == "mdt" ] ||
18109                 error "bad pattern in sub-directory"
18110         [ $($LFS getstripe -c $DIR/$tdir/subdir/second) == 0 ] ||
18111                 error "bad stripe count in sub-directory"
18112         [ $($LFS getstripe -S $DIR/$tdir/subdir/second) == 1048576 ] ||
18113                 error "bad stripe size in sub-directory"
18114         return 0
18115 }
18116 run_test 270c "DoM: DoM EA inheritance tests"
18117
18118 test_270d() {
18119         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18120                 skip "Need MDS version at least 2.10.55"
18121
18122         mkdir -p $DIR/$tdir
18123         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18124
18125         # inherit default DoM striping
18126         mkdir $DIR/$tdir/subdir
18127         touch $DIR/$tdir/subdir/f1
18128
18129         # change default directory striping
18130         $LFS setstripe -c 1 $DIR/$tdir/subdir
18131         touch $DIR/$tdir/subdir/f2
18132         [ $($LFS getstripe -c $DIR/$tdir/subdir/f2) == 1 ] ||
18133                 error "wrong default striping in file 2"
18134         [ $($LFS getstripe -L $DIR/$tdir/subdir/f2) == "raid0" ] ||
18135                 error "bad pattern in file 2"
18136         return 0
18137 }
18138 run_test 270d "DoM: change striping from DoM to RAID0"
18139
18140 test_270e() {
18141         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18142                 skip "Need MDS version at least 2.10.55"
18143
18144         mkdir -p $DIR/$tdir/dom
18145         mkdir -p $DIR/$tdir/norm
18146         DOMFILES=20
18147         NORMFILES=10
18148         $LFS setstripe -E 1M -L mdt $DIR/$tdir/dom
18149         $LFS setstripe -i 0 -S 2M $DIR/$tdir/norm
18150
18151         createmany -o $DIR/$tdir/dom/dom- $DOMFILES
18152         createmany -o $DIR/$tdir/norm/norm- $NORMFILES
18153
18154         # find DoM files by layout
18155         NUM=$($LFS find -L mdt -type f $DIR/$tdir 2>/dev/null | wc -l)
18156         [ $NUM -eq  $DOMFILES ] ||
18157                 error "lfs find -L: found $NUM, expected $DOMFILES"
18158         echo "Test 1: lfs find 20 DOM files by layout: OK"
18159
18160         # there should be 1 dir with default DOM striping
18161         NUM=$($LFS find -L mdt -type d $DIR/$tdir 2>/dev/null | wc -l)
18162         [ $NUM -eq  1 ] ||
18163                 error "lfs find -L: found $NUM, expected 1 dir"
18164         echo "Test 2: lfs find 1 DOM dir by layout: OK"
18165
18166         # find DoM files by stripe size
18167         NUM=$($LFS find -S -1200K -type f $DIR/$tdir 2>/dev/null | wc -l)
18168         [ $NUM -eq  $DOMFILES ] ||
18169                 error "lfs find -S: found $NUM, expected $DOMFILES"
18170         echo "Test 4: lfs find 20 DOM files by stripe size: OK"
18171
18172         # find files by stripe offset except DoM files
18173         NUM=$($LFS find -i 0 -type f $DIR/$tdir 2>/dev/null | wc -l)
18174         [ $NUM -eq  $NORMFILES ] ||
18175                 error "lfs find -i: found $NUM, expected $NORMFILES"
18176         echo "Test 5: lfs find no DOM files by stripe index: OK"
18177         return 0
18178 }
18179 run_test 270e "DoM: lfs find with DoM files test"
18180
18181 test_270f() {
18182         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18183                 skip "Need MDS version at least 2.10.55"
18184
18185         local mdtname=${FSNAME}-MDT0000-mdtlov
18186         local dom=$DIR/$tdir/dom_file
18187         local dom_limit_saved=$(do_facet mds1 $LCTL get_param -n \
18188                                                 lod.$mdtname.dom_stripesize)
18189         local dom_limit=131072
18190
18191         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=$dom_limit
18192         local dom_current=$(do_facet mds1 $LCTL get_param -n \
18193                                                 lod.$mdtname.dom_stripesize)
18194         [ ${dom_limit} -eq ${dom_current} ] ||
18195                 error "Cannot change per-MDT DoM stripe limit to $dom_limit"
18196
18197         $LFS mkdir -i 0 -c 1 $DIR/$tdir
18198         $LFS setstripe -d $DIR/$tdir
18199         $LFS setstripe -E $dom_limit -L mdt $DIR/$tdir ||
18200                 error "Can't set directory default striping"
18201
18202         # exceed maximum stripe size
18203         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18204                 error "Can't create file with $((dom_limit * 2)) DoM stripe"
18205         [ $($LFS getstripe -S $dom) -eq $((dom_limit * 2)) ] &&
18206                 error "Able to create DoM component size more than LOD limit"
18207
18208         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=0
18209         dom_current=$(do_facet mds1 $LCTL get_param -n \
18210                                                 lod.$mdtname.dom_stripesize)
18211         [ 0 -eq ${dom_current} ] ||
18212                 error "Can't set zero DoM stripe limit"
18213         rm $dom
18214
18215         # attempt to create DoM file on server with disabled DoM should
18216         # remove DoM entry from layout and be succeed
18217         $LFS setstripe -E $dom_limit -L mdt -E -1 $dom ||
18218                 error "Can't create DoM file (DoM is disabled)"
18219         [ $($LFS getstripe -L $dom) == "mdt" ] &&
18220                 error "File has DoM component while DoM is disabled"
18221         rm $dom
18222
18223         # attempt to create DoM file with only DoM stripe should return error
18224         $LFS setstripe -E $dom_limit -L mdt $dom &&
18225                 error "Able to create DoM-only file while DoM is disabled"
18226
18227         # too low values to be aligned with smallest stripe size 64K
18228         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=30000
18229         dom_current=$(do_facet mds1 $LCTL get_param -n \
18230                                                 lod.$mdtname.dom_stripesize)
18231         [ 30000 -eq ${dom_current} ] &&
18232                 error "Can set too small DoM stripe limit"
18233
18234         # 64K is a minimal stripe size in Lustre, expect limit of that size
18235         [ 65536 -eq ${dom_current} ] ||
18236                 error "Limit is not set to 64K but ${dom_current}"
18237
18238         do_facet mds1 $LCTL set_param -n lod.$mdtname.dom_stripesize=2147483648
18239         dom_current=$(do_facet mds1 $LCTL get_param -n \
18240                                                 lod.$mdtname.dom_stripesize)
18241         echo $dom_current
18242         [ 2147483648 -eq ${dom_current} ] &&
18243                 error "Can set too large DoM stripe limit"
18244
18245         do_facet mds1 $LCTL set_param -n \
18246                                 lod.$mdtname.dom_stripesize=$((dom_limit * 2))
18247         $LFS setstripe -E $((dom_limit * 2)) -L mdt $dom ||
18248                 error "Can't create DoM component size after limit change"
18249         do_facet mds1 $LCTL set_param -n \
18250                                 lod.$mdtname.dom_stripesize=$((dom_limit / 2))
18251         $LFS setstripe -E $dom_limit -L mdt ${dom}_big ||
18252                 error "Can't create DoM file after limit decrease"
18253         [ $($LFS getstripe -S ${dom}_big) -eq $((dom_limit / 2)) ] ||
18254                 error "Can create big DoM component after limit decrease"
18255         touch ${dom}_def ||
18256                 error "Can't create file with old default layout"
18257
18258         do_facet mds1 $LCTL set_param -n lod.*.dom_stripesize=$dom_limit_saved
18259         return 0
18260 }
18261 run_test 270f "DoM: maximum DoM stripe size checks"
18262
18263 test_271a() {
18264         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18265                 skip "Need MDS version at least 2.10.55"
18266
18267         local dom=$DIR/$tdir/dom
18268
18269         mkdir -p $DIR/$tdir
18270
18271         $LFS setstripe -E 1024K -L mdt $dom
18272
18273         lctl set_param -n mdc.*.stats=clear
18274         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18275         cat $dom > /dev/null
18276         local reads=$(lctl get_param -n mdc.*.stats | grep -c ost_read)
18277         [ $reads -eq 0 ] || error "Unexpected $reads READ RPCs"
18278         ls $dom
18279         rm -f $dom
18280 }
18281 run_test 271a "DoM: data is cached for read after write"
18282
18283 test_271b() {
18284         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18285                 skip "Need MDS version at least 2.10.55"
18286
18287         local dom=$DIR/$tdir/dom
18288
18289         mkdir -p $DIR/$tdir
18290
18291         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18292
18293         lctl set_param -n mdc.*.stats=clear
18294         dd if=/dev/zero of=$dom bs=4096 count=1 || return 1
18295         cancel_lru_locks mdc
18296         $CHECKSTAT -t file -s 4096 $dom || error "stat #1 fails"
18297         # second stat to check size is cached on client
18298         $CHECKSTAT -t file -s 4096 $dom || error "stat #2 fails"
18299         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18300         [ $gls -eq 0 ] || error "Unexpected $gls glimpse RPCs"
18301         rm -f $dom
18302 }
18303 run_test 271b "DoM: no glimpse RPC for stat (DoM only file)"
18304
18305 test_271ba() {
18306         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18307                 skip "Need MDS version at least 2.10.55"
18308
18309         local dom=$DIR/$tdir/dom
18310
18311         mkdir -p $DIR/$tdir
18312
18313         $LFS setstripe -E 1024K -L mdt -E EOF $dom
18314
18315         lctl set_param -n mdc.*.stats=clear
18316         lctl set_param -n osc.*.stats=clear
18317         dd if=/dev/zero of=$dom bs=2048K count=1 || return 1
18318         cancel_lru_locks mdc
18319         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18320         # second stat to check size is cached on client
18321         $CHECKSTAT -t file -s 2097152 $dom || error "stat"
18322         local gls=$(lctl get_param -n mdc.*.stats | grep -c ldlm_glimpse)
18323         [ $gls == 0 ] || error "Unexpected $gls glimpse RPCs"
18324         local gls=$(lctl get_param -n osc.*.stats | grep -c ldlm_glimpse)
18325         [ $gls == 0 ] || error "Unexpected $gls OSC glimpse RPCs"
18326         rm -f $dom
18327 }
18328 run_test 271ba "DoM: no glimpse RPC for stat (combined file)"
18329
18330
18331 get_mdc_stats() {
18332         local mdtidx=$1
18333         local param=$2
18334         local mdt=MDT$(printf %04x $mdtidx)
18335
18336         if [ -z $param ]; then
18337                 lctl get_param -n mdc.*$mdt*.stats
18338         else
18339                 lctl get_param -n mdc.*$mdt*.stats | awk "/$param/"'{print $2}'
18340         fi
18341 }
18342
18343 test_271c() {
18344         [ $MDS1_VERSION -lt $(version_code 2.10.55) ] &&
18345                 skip "Need MDS version at least 2.10.55"
18346
18347         local dom=$DIR/$tdir/dom
18348
18349         mkdir -p $DIR/$tdir
18350
18351         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18352
18353         local mdtidx=$($LFS getstripe -m $DIR/$tdir)
18354         local facet=mds$((mdtidx + 1))
18355
18356         cancel_lru_locks mdc
18357         do_facet $facet lctl set_param -n mdt.*.dom_lock=0
18358         createmany -o $dom 1000
18359         lctl set_param -n mdc.*.stats=clear
18360         smalliomany -w $dom 1000 200
18361         get_mdc_stats $mdtidx
18362         local enq=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18363         # Each file has 1 open, 1 IO enqueues, total 2000
18364         # but now we have also +1 getxattr for security.capability, total 3000
18365         [ $enq -ge 2000 ] || error "Too few enqueues $enq, expected > 2000"
18366         unlinkmany $dom 1000
18367
18368         cancel_lru_locks mdc
18369         do_facet $facet lctl set_param -n mdt.*.dom_lock=1
18370         createmany -o $dom 1000
18371         lctl set_param -n mdc.*.stats=clear
18372         smalliomany -w $dom 1000 200
18373         local enq_2=$(get_mdc_stats $mdtidx ldlm_ibits_enqueue)
18374         # Expect to see reduced amount of RPCs by 1000 due to single enqueue
18375         # for OPEN and IO lock.
18376         [ $((enq - enq_2)) -ge 1000 ] ||
18377                 error "Too many enqueues $enq_2, expected about $((enq - 1000))"
18378         unlinkmany $dom 1000
18379         return 0
18380 }
18381 run_test 271c "DoM: IO lock at open saves enqueue RPCs"
18382
18383 cleanup_271def_tests() {
18384         trap 0
18385         rm -f $1
18386 }
18387
18388 test_271d() {
18389         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18390                 skip "Need MDS version at least 2.10.57"
18391
18392         local dom=$DIR/$tdir/dom
18393         local tmp=$TMP/$tfile
18394         trap "cleanup_271def_tests $tmp" EXIT
18395
18396         mkdir -p $DIR/$tdir
18397
18398         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18399
18400         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18401
18402         cancel_lru_locks mdc
18403         dd if=/dev/urandom of=$tmp bs=1000 count=1
18404         dd if=$tmp of=$dom bs=1000 count=1
18405         cancel_lru_locks mdc
18406
18407         cat /etc/hosts >> $tmp
18408         lctl set_param -n mdc.*.stats=clear
18409
18410         # append data to the same file it should update local page
18411         echo "Append to the same page"
18412         cat /etc/hosts >> $dom
18413         local num=$(get_mdc_stats $mdtidx ost_read)
18414         local ra=$(get_mdc_stats $mdtidx req_active)
18415         local rw=$(get_mdc_stats $mdtidx req_waittime)
18416
18417         [ -z $num ] || error "$num READ RPC occured"
18418         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18419         echo "... DONE"
18420
18421         # compare content
18422         cmp $tmp $dom || error "file miscompare"
18423
18424         cancel_lru_locks mdc
18425         lctl set_param -n mdc.*.stats=clear
18426
18427         echo "Open and read file"
18428         cat $dom > /dev/null
18429         local num=$(get_mdc_stats $mdtidx ost_read)
18430         local ra=$(get_mdc_stats $mdtidx req_active)
18431         local rw=$(get_mdc_stats $mdtidx req_waittime)
18432
18433         [ -z $num ] || error "$num READ RPC occured"
18434         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18435         echo "... DONE"
18436
18437         # compare content
18438         cmp $tmp $dom || error "file miscompare"
18439
18440         return 0
18441 }
18442 run_test 271d "DoM: read on open (1K file in reply buffer)"
18443
18444 test_271f() {
18445         [ $MDS1_VERSION -lt $(version_code 2.10.57) ] &&
18446                 skip "Need MDS version at least 2.10.57"
18447
18448         local dom=$DIR/$tdir/dom
18449         local tmp=$TMP/$tfile
18450         trap "cleanup_271def_tests $tmp" EXIT
18451
18452         mkdir -p $DIR/$tdir
18453
18454         $LFS setstripe -E 1024K -L mdt $DIR/$tdir
18455
18456         local mdtidx=$($LFS getstripe --mdt-index $DIR/$tdir)
18457
18458         cancel_lru_locks mdc
18459         dd if=/dev/urandom of=$tmp bs=265000 count=1
18460         dd if=$tmp of=$dom bs=265000 count=1
18461         cancel_lru_locks mdc
18462         cat /etc/hosts >> $tmp
18463         lctl set_param -n mdc.*.stats=clear
18464
18465         echo "Append to the same page"
18466         cat /etc/hosts >> $dom
18467         local num=$(get_mdc_stats $mdtidx ost_read)
18468         local ra=$(get_mdc_stats $mdtidx req_active)
18469         local rw=$(get_mdc_stats $mdtidx req_waittime)
18470
18471         [ -z $num ] || error "$num READ RPC occured"
18472         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18473         echo "... DONE"
18474
18475         # compare content
18476         cmp $tmp $dom || error "file miscompare"
18477
18478         cancel_lru_locks mdc
18479         lctl set_param -n mdc.*.stats=clear
18480
18481         echo "Open and read file"
18482         cat $dom > /dev/null
18483         local num=$(get_mdc_stats $mdtidx ost_read)
18484         local ra=$(get_mdc_stats $mdtidx req_active)
18485         local rw=$(get_mdc_stats $mdtidx req_waittime)
18486
18487         [ -z $num ] && num=0
18488         [ $num -eq 1 ] || error "expect 1 READ RPC, $num occured"
18489         [ $ra == $rw ] || error "$((ra - rw)) resend occured"
18490         echo "... DONE"
18491
18492         # compare content
18493         cmp $tmp $dom || error "file miscompare"
18494
18495         return 0
18496 }
18497 run_test 271f "DoM: read on open (200K file and read tail)"
18498
18499 test_271g() {
18500         [[ $($LCTL get_param mdc.*.import) =~ async_discard ]] ||
18501                 skip "Skipping due to old client or server version"
18502
18503         $LFS setstripe -E 1024K -L mdt -E EOF $DIR1/$tfile
18504         # to get layout
18505         $CHECKSTAT -t file $DIR1/$tfile
18506
18507         $MULTIOP $DIR1/$tfile Ow40960_w4096c &
18508         MULTIOP_PID=$!
18509         sleep 1
18510         #define OBD_FAIL_LDLM_CANCEL_BL_CB_RACE
18511         $LCTL set_param fail_loc=0x80000314
18512         rm $DIR1/$tfile || error "Unlink fails"
18513         RC=$?
18514         kill -USR1 $MULTIOP_PID && wait $MULTIOP_PID || error "multiop failure"
18515         [ $RC -eq 0 ] || error "Failed write to stale object"
18516 }
18517 run_test 271g "Discard DoM data vs client flush race"
18518
18519 test_272a() {
18520         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18521                 skip "Need MDS version at least 2.11.50"
18522
18523         local dom=$DIR/$tdir/dom
18524         mkdir -p $DIR/$tdir
18525
18526         $LFS setstripe -E 256K -L mdt -E -1 -c1 $dom
18527         dd if=/dev/urandom of=$dom bs=512K count=1 ||
18528                 error "failed to write data into $dom"
18529         local old_md5=$(md5sum $dom)
18530
18531         $LFS migrate -E 256K -L mdt -E -1 -c2 $dom ||
18532                 error "failed to migrate to the same DoM component"
18533
18534         local new_md5=$(md5sum $dom)
18535
18536         [ "$old_md5" == "$new_md5" ] ||
18537                 error "md5sum differ: $old_md5, $new_md5"
18538
18539         [ $($LFS getstripe -c $dom) -eq 2 ] ||
18540                 error "migrate stripe count bad: $(LFS getstripe -c $dom) != 2"
18541 }
18542 run_test 272a "DoM migration: new layout with the same DOM component"
18543
18544 test_272b() {
18545         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18546                 skip "Need MDS version at least 2.11.50"
18547
18548         local dom=$DIR/$tdir/dom
18549         mkdir -p $DIR/$tdir
18550         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18551
18552         local mdtidx=$($LFS getstripe -m $dom)
18553         local mdtname=MDT$(printf %04x $mdtidx)
18554         local facet=mds$((mdtidx + 1))
18555
18556         local mdtfree1=$(do_facet $facet \
18557                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18558         dd if=/dev/urandom of=$dom bs=2M count=1 ||
18559                 error "failed to write data into $dom"
18560         local old_md5=$(md5sum $dom)
18561         cancel_lru_locks mdc
18562         local mdtfree1=$(do_facet $facet \
18563                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18564
18565         $LFS migrate -c2 $dom ||
18566                 error "failed to migrate to the new composite layout"
18567         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18568                 error "MDT stripe was not removed"
18569
18570         cancel_lru_locks mdc
18571         local new_md5=$(md5sum $dom)
18572         [ "$old_md5" == "$new_md5" ] ||
18573                 error "$old_md5 != $new_md5"
18574
18575         # Skip free space checks with ZFS
18576         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18577                 local mdtfree2=$(do_facet $facet \
18578                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18579                 [ $mdtfree2 -gt $mdtfree1 ] ||
18580                         error "MDT space is not freed after migration"
18581         fi
18582         return 0
18583 }
18584 run_test 272b "DoM migration: DOM file to the OST-striped file (plain)"
18585
18586 test_272c() {
18587         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18588                 skip "Need MDS version at least 2.11.50"
18589
18590         local dom=$DIR/$tdir/$tfile
18591         mkdir -p $DIR/$tdir
18592         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18593
18594         local mdtidx=$($LFS getstripe -m $dom)
18595         local mdtname=MDT$(printf %04x $mdtidx)
18596         local facet=mds$((mdtidx + 1))
18597
18598         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18599                 error "failed to write data into $dom"
18600         local old_md5=$(md5sum $dom)
18601         cancel_lru_locks mdc
18602         local mdtfree1=$(do_facet $facet \
18603                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18604
18605         $LFS migrate -E 2M -c1 -E -1 -c2 $dom ||
18606                 error "failed to migrate to the new composite layout"
18607         [ $($LFS getstripe -L $dom) == 'mdt' ] &&
18608                 error "MDT stripe was not removed"
18609
18610         cancel_lru_locks mdc
18611         local new_md5=$(md5sum $dom)
18612         [ "$old_md5" == "$new_md5" ] ||
18613                 error "$old_md5 != $new_md5"
18614
18615         # Skip free space checks with ZFS
18616         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18617                 local mdtfree2=$(do_facet $facet \
18618                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18619                 [ $mdtfree2 -gt $mdtfree1 ] ||
18620                         error "MDS space is not freed after migration"
18621         fi
18622         return 0
18623 }
18624 run_test 272c "DoM migration: DOM file to the OST-striped file (composite)"
18625
18626 test_272d() {
18627         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18628                 skip "Need MDS version at least 2.12.55"
18629
18630         local dom=$DIR/$tdir/$tfile
18631         mkdir -p $DIR/$tdir
18632         $LFS setstripe -E 1M -L mdt -E -1 -c1 $dom
18633
18634         local mdtidx=$($LFS getstripe -m $dom)
18635         local mdtname=MDT$(printf %04x $mdtidx)
18636         local facet=mds$((mdtidx + 1))
18637
18638         dd if=/dev/urandom of=$dom bs=2M count=1 oflag=direct ||
18639                 error "failed to write data into $dom"
18640         local old_md5=$(md5sum $dom)
18641         cancel_lru_locks mdc
18642         local mdtfree1=$(do_facet $facet \
18643                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18644
18645         $LFS mirror extend -N -E 2M -c1 -E -1 -c2 $dom ||
18646                 error "failed mirroring to the new composite layout"
18647         $LFS mirror resync $dom ||
18648                 error "failed mirror resync"
18649         $LFS mirror split --mirror-id 1 -d $dom ||
18650                 error "failed mirror split"
18651
18652         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18653                 error "MDT stripe was not removed"
18654
18655         cancel_lru_locks mdc
18656         local new_md5=$(md5sum $dom)
18657         [ "$old_md5" == "$new_md5" ] ||
18658                 error "$old_md5 != $new_md5"
18659
18660         # Skip free space checks with ZFS
18661         if [ "$(facet_fstype $facet)" != "zfs" ]; then
18662                 local mdtfree2=$(do_facet $facet \
18663                                 lctl get_param -n osd*.*$mdtname.kbytesfree)
18664                 [ $mdtfree2 -gt $mdtfree1 ] ||
18665                         error "MDS space is not freed after DOM mirror deletion"
18666         fi
18667         return 0
18668 }
18669 run_test 272d "DoM mirroring: OST-striped mirror to DOM file"
18670
18671 test_272e() {
18672         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18673                 skip "Need MDS version at least 2.12.55"
18674
18675         local dom=$DIR/$tdir/$tfile
18676         mkdir -p $DIR/$tdir
18677         $LFS setstripe -c 2 $dom
18678
18679         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18680                 error "failed to write data into $dom"
18681         local old_md5=$(md5sum $dom)
18682         cancel_lru_locks mdc
18683
18684         $LFS mirror extend -N -E 1M -L mdt -E eof -c2 $dom ||
18685                 error "failed mirroring to the DOM layout"
18686         $LFS mirror resync $dom ||
18687                 error "failed mirror resync"
18688         $LFS mirror split --mirror-id 1 -d $dom ||
18689                 error "failed mirror split"
18690
18691         [ $($LFS getstripe -L $dom) != 'mdt' ] ||
18692                 error "MDT stripe was not removed"
18693
18694         cancel_lru_locks mdc
18695         local new_md5=$(md5sum $dom)
18696         [ "$old_md5" == "$new_md5" ] ||
18697                 error "$old_md5 != $new_md5"
18698
18699         return 0
18700 }
18701 run_test 272e "DoM mirroring: DOM mirror to the OST-striped file"
18702
18703 test_272f() {
18704         [ $MDS1_VERSION -lt $(version_code 2.12.55) ] &&
18705                 skip "Need MDS version at least 2.12.55"
18706
18707         local dom=$DIR/$tdir/$tfile
18708         mkdir -p $DIR/$tdir
18709         $LFS setstripe -c 2 $dom
18710
18711         dd if=/dev/urandom of=$dom bs=512K count=1 oflag=direct ||
18712                 error "failed to write data into $dom"
18713         local old_md5=$(md5sum $dom)
18714         cancel_lru_locks mdc
18715
18716         $LFS migrate -E 1M -L mdt -E eof -c2 -v $dom ||
18717                 error "failed migrating to the DOM file"
18718
18719         cancel_lru_locks mdc
18720         local new_md5=$(md5sum $dom)
18721         [ "$old_md5" != "$new_md5" ] &&
18722                 error "$old_md5 != $new_md5"
18723
18724         return 0
18725 }
18726 run_test 272f "DoM migration: OST-striped file to DOM file"
18727
18728 test_273a() {
18729         [ $MDS1_VERSION -lt $(version_code 2.11.50) ] &&
18730                 skip "Need MDS version at least 2.11.50"
18731
18732         # Layout swap cannot be done if either file has DOM component,
18733         # this will never be supported, migration should be used instead
18734
18735         local dom=$DIR/$tdir/$tfile
18736         mkdir -p $DIR/$tdir
18737
18738         $LFS setstripe -c2 ${dom}_plain
18739         $LFS setstripe -E 1M -L mdt -E -1 -c2 ${dom}_dom
18740         $LFS swap_layouts ${dom}_plain ${dom}_dom &&
18741                 error "can swap layout with DoM component"
18742         $LFS swap_layouts ${dom}_dom ${dom}_plain &&
18743                 error "can swap layout with DoM component"
18744
18745         $LFS setstripe -E 1M -c1 -E -1 -c2 ${dom}_comp
18746         $LFS swap_layouts ${dom}_comp ${dom}_dom &&
18747                 error "can swap layout with DoM component"
18748         $LFS swap_layouts ${dom}_dom ${dom}_comp &&
18749                 error "can swap layout with DoM component"
18750         return 0
18751 }
18752 run_test 273a "DoM: layout swapping should fail with DOM"
18753
18754 test_275() {
18755         remote_ost_nodsh && skip "remote OST with nodsh"
18756         [ $OST1_VERSION -lt $(version_code 2.10.57) ] &&
18757                 skip "Need OST version >= 2.10.57"
18758
18759         local file=$DIR/$tfile
18760         local oss
18761
18762         oss=$(comma_list $(osts_nodes))
18763
18764         dd if=/dev/urandom of=$file bs=1M count=2 ||
18765                 error "failed to create a file"
18766         cancel_lru_locks osc
18767
18768         #lock 1
18769         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18770                 error "failed to read a file"
18771
18772 #define OBD_FAIL_LDLM_PAUSE_CANCEL2      0x31f
18773         $LCTL set_param fail_loc=0x8000031f
18774
18775         cancel_lru_locks osc &
18776         sleep 1
18777
18778 #define OBD_FAIL_LDLM_PROLONG_PAUSE      0x32b
18779         do_nodes $oss $LCTL set_param fail_loc=0x8000032b
18780         #IO takes another lock, but matches the PENDING one
18781         #and places it to the IO RPC
18782         dd if=$file of=/dev/null bs=1M count=1 iflag=direct ||
18783                 error "failed to read a file with PENDING lock"
18784 }
18785 run_test 275 "Read on a canceled duplicate lock"
18786
18787 test_276() {
18788         remote_ost_nodsh && skip "remote OST with nodsh"
18789         local pid
18790
18791         do_facet ost1 "(while true; do \
18792                 $LCTL get_param obdfilter.*.filesfree > /dev/null 2>&1; \
18793                 done) & pid=\\\$!; echo \\\$pid > $TMP/sanity_276_pid" &
18794         pid=$!
18795
18796         for LOOP in $(seq 20); do
18797                 stop ost1
18798                 start ost1 $(ostdevname 1) $OST_MOUNT_OPTS
18799         done
18800         kill -9 $pid
18801         do_facet ost1 "pid=\\\$(cat $TMP/sanity_276_pid); kill -9 \\\$pid; \
18802                 rm $TMP/sanity_276_pid"
18803 }
18804 run_test 276 "Race between mount and obd_statfs"
18805
18806 test_277() {
18807         $LCTL set_param ldlm.namespaces.*.lru_size=0
18808         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1
18809         local cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18810                         grep ^used_mb | awk '{print $2}')
18811         [ $cached_mb -eq 1 ] || error "expected mb 1 got $cached_mb"
18812         dd if=/dev/zero of=$DIR/$tfile bs=1M count=1 \
18813                 oflag=direct conv=notrunc
18814         cached_mb=$($LCTL get_param llite.*.max_cached_mb |
18815                         grep ^used_mb | awk '{print $2}')
18816         [ $cached_mb -eq 0 ] || error "expected mb 0 got $cached_mb"
18817 }
18818 run_test 277 "Direct IO shall drop page cache"
18819
18820 test_278() {
18821         [ $PARALLEL == "yes" ] && skip "skip parallel run" && return
18822         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
18823         [[ "$(facet_host mds1)" != "$(facet_host mds2)" ]] &&
18824                 skip "needs the same host for mdt1 mdt2" && return
18825
18826         local pid1
18827         local pid2
18828
18829 #define OBD_FAIL_OBD_STOP_MDS_RACE     0x60b
18830         do_facet mds2 $LCTL set_param fail_loc=0x8000060c
18831         stop mds2 &
18832         pid2=$!
18833
18834         stop mds1
18835
18836         echo "Starting MDTs"
18837         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
18838         wait $pid2
18839 #For the error assertion will happen. lu_env_get_key(..., &mdt_thread_key)
18840 #will return NULL
18841         do_facet mds2 $LCTL set_param fail_loc=0
18842
18843         start mds2 $(mdsdevname 2) $MDS_MOUNT_OPTS
18844         wait_recovery_complete mds2
18845 }
18846 run_test 278 "Race starting MDS between MDTs stop/start"
18847
18848 cleanup_test_300() {
18849         trap 0
18850         umask $SAVE_UMASK
18851 }
18852 test_striped_dir() {
18853         local mdt_index=$1
18854         local stripe_count
18855         local stripe_index
18856
18857         mkdir -p $DIR/$tdir
18858
18859         SAVE_UMASK=$(umask)
18860         trap cleanup_test_300 RETURN EXIT
18861
18862         $LFS setdirstripe -i $mdt_index -c 2 -H all_char -o 755 \
18863                                                 $DIR/$tdir/striped_dir ||
18864                 error "set striped dir error"
18865
18866         local mode=$(stat -c%a $DIR/$tdir/striped_dir)
18867         [ "$mode" = "755" ] || error "expect 755 got $mode"
18868
18869         $LFS getdirstripe $DIR/$tdir/striped_dir > /dev/null 2>&1 ||
18870                 error "getdirstripe failed"
18871         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir)
18872         if [ "$stripe_count" != "2" ]; then
18873                 error "1:stripe_count is $stripe_count, expect 2"
18874         fi
18875         stripe_count=$($LFS getdirstripe -T $DIR/$tdir/striped_dir)
18876         if [ "$stripe_count" != "2" ]; then
18877                 error "2:stripe_count is $stripe_count, expect 2"
18878         fi
18879
18880         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir)
18881         if [ "$stripe_index" != "$mdt_index" ]; then
18882                 error "stripe_index is $stripe_index, expect $mdt_index"
18883         fi
18884
18885         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18886                 error "nlink error after create striped dir"
18887
18888         mkdir $DIR/$tdir/striped_dir/a
18889         mkdir $DIR/$tdir/striped_dir/b
18890
18891         stat $DIR/$tdir/striped_dir/a ||
18892                 error "create dir under striped dir failed"
18893         stat $DIR/$tdir/striped_dir/b ||
18894                 error "create dir under striped dir failed"
18895
18896         [ $(stat -c%h $DIR/$tdir/striped_dir) == '4' ] ||
18897                 error "nlink error after mkdir"
18898
18899         rmdir $DIR/$tdir/striped_dir/a
18900         [ $(stat -c%h $DIR/$tdir/striped_dir) == '3' ] ||
18901                 error "nlink error after rmdir"
18902
18903         rmdir $DIR/$tdir/striped_dir/b
18904         [ $(stat -c%h $DIR/$tdir/striped_dir) == '2' ] ||
18905                 error "nlink error after rmdir"
18906
18907         chattr +i $DIR/$tdir/striped_dir
18908         createmany -o $DIR/$tdir/striped_dir/f 10 &&
18909                 error "immutable flags not working under striped dir!"
18910         chattr -i $DIR/$tdir/striped_dir
18911
18912         rmdir $DIR/$tdir/striped_dir ||
18913                 error "rmdir striped dir error"
18914
18915         cleanup_test_300
18916
18917         true
18918 }
18919
18920 test_300a() {
18921         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18922                 skip "skipped for lustre < 2.7.0"
18923         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18924         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18925
18926         test_striped_dir 0 || error "failed on striped dir on MDT0"
18927         test_striped_dir 1 || error "failed on striped dir on MDT0"
18928 }
18929 run_test 300a "basic striped dir sanity test"
18930
18931 test_300b() {
18932         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18933                 skip "skipped for lustre < 2.7.0"
18934         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18935         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18936
18937         local i
18938         local mtime1
18939         local mtime2
18940         local mtime3
18941
18942         test_mkdir $DIR/$tdir || error "mkdir fail"
18943         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
18944                 error "set striped dir error"
18945         for i in {0..9}; do
18946                 mtime1=$(stat -c %Y $DIR/$tdir/striped_dir)
18947                 sleep 1
18948                 touch $DIR/$tdir/striped_dir/file_$i || error "touch error $i"
18949                 mtime2=$(stat -c %Y $DIR/$tdir/striped_dir)
18950                 [ $mtime1 -eq $mtime2 ] && error "mtime unchanged after create"
18951                 sleep 1
18952                 rm -f $DIR/$tdir/striped_dir/file_$i || error "unlink error $i"
18953                 mtime3=$(stat -c %Y $DIR/$tdir/striped_dir)
18954                 [ $mtime2 -eq $mtime3 ] && error "mtime unchanged after unlink"
18955         done
18956         true
18957 }
18958 run_test 300b "check ctime/mtime for striped dir"
18959
18960 test_300c() {
18961         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18962                 skip "skipped for lustre < 2.7.0"
18963         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18964         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18965
18966         local file_count
18967
18968         mkdir -p $DIR/$tdir
18969         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir ||
18970                 error "set striped dir error"
18971
18972         chown $RUNAS_ID:$RUNAS_GID $DIR/$tdir/striped_dir ||
18973                 error "chown striped dir failed"
18974
18975         $RUNAS createmany -o $DIR/$tdir/striped_dir/f 5000 ||
18976                 error "create 5k files failed"
18977
18978         file_count=$(ls $DIR/$tdir/striped_dir | wc -l)
18979
18980         [ "$file_count" = 5000 ] || error "file count $file_count != 5000"
18981
18982         rm -rf $DIR/$tdir
18983 }
18984 run_test 300c "chown && check ls under striped directory"
18985
18986 test_300d() {
18987         [ $MDS1_VERSION -lt $(version_code 2.7.0) ] &&
18988                 skip "skipped for lustre < 2.7.0"
18989         [ $PARALLEL == "yes" ] && skip "skip parallel run"
18990         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
18991
18992         local stripe_count
18993         local file
18994
18995         mkdir -p $DIR/$tdir
18996         $LFS setstripe -c 2 $DIR/$tdir
18997
18998         #local striped directory
18999         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19000                 error "set striped dir error"
19001         createmany -o $DIR/$tdir/striped_dir/f 10 ||
19002                 error "create 10 files failed"
19003
19004         #remote striped directory
19005         $LFS setdirstripe -i 1 -c 2 $DIR/$tdir/remote_striped_dir ||
19006                 error "set striped dir error"
19007         createmany -o $DIR/$tdir/remote_striped_dir/f 10 ||
19008                 error "create 10 files failed"
19009
19010         for file in $(find $DIR/$tdir); do
19011                 stripe_count=$($LFS getstripe -c $file)
19012                 [ $stripe_count -eq 2 ] ||
19013                         error "wrong stripe $stripe_count for $file"
19014         done
19015
19016         rm -rf $DIR/$tdir
19017 }
19018 run_test 300d "check default stripe under striped directory"
19019
19020 test_300e() {
19021         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19022                 skip "Need MDS version at least 2.7.55"
19023         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19024         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19025
19026         local stripe_count
19027         local file
19028
19029         mkdir -p $DIR/$tdir
19030
19031         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19032                 error "set striped dir error"
19033
19034         touch $DIR/$tdir/striped_dir/a
19035         touch $DIR/$tdir/striped_dir/b
19036         touch $DIR/$tdir/striped_dir/c
19037
19038         mkdir $DIR/$tdir/striped_dir/dir_a
19039         mkdir $DIR/$tdir/striped_dir/dir_b
19040         mkdir $DIR/$tdir/striped_dir/dir_c
19041
19042         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_a ||
19043                 error "set striped adir under striped dir error"
19044
19045         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_b ||
19046                 error "set striped bdir under striped dir error"
19047
19048         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir/stp_c ||
19049                 error "set striped cdir under striped dir error"
19050
19051         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir/dir_b ||
19052                 error "rename dir under striped dir fails"
19053
19054         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir/stp_b ||
19055                 error "rename dir under different stripes fails"
19056
19057         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir/c ||
19058                 error "rename file under striped dir should succeed"
19059
19060         mrename $DIR/$tdir/striped_dir/dir_b $DIR/$tdir/striped_dir/dir_c ||
19061                 error "rename dir under striped dir should succeed"
19062
19063         rm -rf $DIR/$tdir
19064 }
19065 run_test 300e "check rename under striped directory"
19066
19067 test_300f() {
19068         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19069         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19070         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19071                 skip "Need MDS version at least 2.7.55"
19072
19073         local stripe_count
19074         local file
19075
19076         rm -rf $DIR/$tdir
19077         mkdir -p $DIR/$tdir
19078
19079         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir ||
19080                 error "set striped dir error"
19081
19082         $LFS setdirstripe -i 0 -c 2 -H all_char $DIR/$tdir/striped_dir1 ||
19083                 error "set striped dir error"
19084
19085         touch $DIR/$tdir/striped_dir/a
19086         mkdir $DIR/$tdir/striped_dir/dir_a
19087         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_a ||
19088                 error "create striped dir under striped dir fails"
19089
19090         touch $DIR/$tdir/striped_dir1/b
19091         mkdir $DIR/$tdir/striped_dir1/dir_b
19092         $LFS setdirstripe -i 0 -c 2 $DIR/$tdir/striped_dir/stp_b ||
19093                 error "create striped dir under striped dir fails"
19094
19095         mrename $DIR/$tdir/striped_dir/dir_a $DIR/$tdir/striped_dir1/dir_b ||
19096                 error "rename dir under different striped dir should fail"
19097
19098         mrename $DIR/$tdir/striped_dir/stp_a $DIR/$tdir/striped_dir1/stp_b ||
19099                 error "rename striped dir under diff striped dir should fail"
19100
19101         mrename $DIR/$tdir/striped_dir/a $DIR/$tdir/striped_dir1/a ||
19102                 error "rename file under diff striped dirs fails"
19103
19104         rm -rf $DIR/$tdir
19105 }
19106 run_test 300f "check rename cross striped directory"
19107
19108 test_300_check_default_striped_dir()
19109 {
19110         local dirname=$1
19111         local default_count=$2
19112         local default_index=$3
19113         local stripe_count
19114         local stripe_index
19115         local dir_stripe_index
19116         local dir
19117
19118         echo "checking $dirname $default_count $default_index"
19119         $LFS setdirstripe -D -c $default_count -i $default_index \
19120                                 -t all_char $DIR/$tdir/$dirname ||
19121                 error "set default stripe on striped dir error"
19122         stripe_count=$($LFS getdirstripe -D -c $DIR/$tdir/$dirname)
19123         [ $stripe_count -eq $default_count ] ||
19124                 error "expect $default_count get $stripe_count for $dirname"
19125
19126         stripe_index=$($LFS getdirstripe -D -i $DIR/$tdir/$dirname)
19127         [ $stripe_index -eq $default_index ] ||
19128                 error "expect $default_index get $stripe_index for $dirname"
19129
19130         mkdir $DIR/$tdir/$dirname/{test1,test2,test3,test4} ||
19131                                                 error "create dirs failed"
19132
19133         createmany -o $DIR/$tdir/$dirname/f- 10 || error "create files failed"
19134         unlinkmany $DIR/$tdir/$dirname/f- 10    || error "unlink files failed"
19135         for dir in $(find $DIR/$tdir/$dirname/*); do
19136                 stripe_count=$($LFS getdirstripe -c $dir)
19137                 [ $stripe_count -eq $default_count ] ||
19138                 [ $stripe_count -eq 0 ] || [ $default_count -eq 1 ] ||
19139                 error "stripe count $default_count != $stripe_count for $dir"
19140
19141                 stripe_index=$($LFS getdirstripe -i $dir)
19142                 [ $default_index -eq -1 ] ||
19143                         [ $stripe_index -eq $default_index ] ||
19144                         error "$stripe_index != $default_index for $dir"
19145
19146                 #check default stripe
19147                 stripe_count=$($LFS getdirstripe -D -c $dir)
19148                 [ $stripe_count -eq $default_count ] ||
19149                 error "default count $default_count != $stripe_count for $dir"
19150
19151                 stripe_index=$($LFS getdirstripe -D -i $dir)
19152                 [ $stripe_index -eq $default_index ] ||
19153                 error "default index $default_index != $stripe_index for $dir"
19154         done
19155         rmdir $DIR/$tdir/$dirname/* || error "rmdir failed"
19156 }
19157
19158 test_300g() {
19159         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19160         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19161                 skip "Need MDS version at least 2.7.55"
19162
19163         local dir
19164         local stripe_count
19165         local stripe_index
19166
19167         mkdir $DIR/$tdir
19168         mkdir $DIR/$tdir/normal_dir
19169
19170         #Checking when client cache stripe index
19171         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
19172         $LFS setdirstripe -D -i1 $DIR/$tdir/striped_dir ||
19173                 error "create striped_dir failed"
19174
19175         $LFS setdirstripe -i0 $DIR/$tdir/striped_dir/dir0 ||
19176                 error "create dir0 fails"
19177         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir0)
19178         [ $stripe_index -eq 0 ] ||
19179                 error "dir0 expect index 0 got $stripe_index"
19180
19181         mkdir $DIR/$tdir/striped_dir/dir1 ||
19182                 error "create dir1 fails"
19183         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/dir1)
19184         [ $stripe_index -eq 1 ] ||
19185                 error "dir1 expect index 1 got $stripe_index"
19186
19187         #check default stripe count/stripe index
19188         test_300_check_default_striped_dir normal_dir $MDSCOUNT 1
19189         test_300_check_default_striped_dir normal_dir 1 0
19190         test_300_check_default_striped_dir normal_dir 2 1
19191         test_300_check_default_striped_dir normal_dir 2 -1
19192
19193         #delete default stripe information
19194         echo "delete default stripeEA"
19195         $LFS setdirstripe -d $DIR/$tdir/normal_dir ||
19196                 error "set default stripe on striped dir error"
19197
19198         mkdir -p $DIR/$tdir/normal_dir/{test1,test2,test3,test4}
19199         for dir in $(find $DIR/$tdir/normal_dir/*); do
19200                 stripe_count=$($LFS getdirstripe -c $dir)
19201                 [ $stripe_count -eq 0 ] ||
19202                         error "expect 1 get $stripe_count for $dir"
19203                 stripe_index=$($LFS getdirstripe -i $dir)
19204                 [ $stripe_index -eq 0 ] ||
19205                         error "expect 0 get $stripe_index for $dir"
19206         done
19207 }
19208 run_test 300g "check default striped directory for normal directory"
19209
19210 test_300h() {
19211         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19212         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19213                 skip "Need MDS version at least 2.7.55"
19214
19215         local dir
19216         local stripe_count
19217
19218         mkdir $DIR/$tdir
19219         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19220                 error "set striped dir error"
19221
19222         test_300_check_default_striped_dir striped_dir $MDSCOUNT 1
19223         test_300_check_default_striped_dir striped_dir 1 0
19224         test_300_check_default_striped_dir striped_dir 2 1
19225         test_300_check_default_striped_dir striped_dir 2 -1
19226
19227         #delete default stripe information
19228         $LFS setdirstripe -d $DIR/$tdir/striped_dir ||
19229                 error "set default stripe on striped dir error"
19230
19231         mkdir -p $DIR/$tdir/striped_dir/{test1,test2,test3,test4}
19232         for dir in $(find $DIR/$tdir/striped_dir/*); do
19233                 stripe_count=$($LFS getdirstripe -c $dir)
19234                 [ $stripe_count -eq 0 ] ||
19235                         error "expect 1 get $stripe_count for $dir"
19236         done
19237 }
19238 run_test 300h "check default striped directory for striped directory"
19239
19240 test_300i() {
19241         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19242         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19243         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19244                 skip "Need MDS version at least 2.7.55"
19245
19246         local stripe_count
19247         local file
19248
19249         mkdir $DIR/$tdir
19250
19251         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19252                 error "set striped dir error"
19253
19254         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19255                 error "create files under striped dir failed"
19256
19257         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir ||
19258                 error "set striped hashdir error"
19259
19260         $LFS setdirstripe -i0 -c$MDSCOUNT -H all_char $DIR/$tdir/hashdir/d0 ||
19261                 error "create dir0 under hash dir failed"
19262         $LFS setdirstripe -i0 -c$MDSCOUNT -H fnv_1a_64 $DIR/$tdir/hashdir/d1 ||
19263                 error "create dir1 under hash dir failed"
19264
19265         # unfortunately, we need to umount to clear dir layout cache for now
19266         # once we fully implement dir layout, we can drop this
19267         umount_client $MOUNT || error "umount failed"
19268         mount_client $MOUNT || error "mount failed"
19269
19270         $LFS find -H fnv_1a_64 $DIR/$tdir/hashdir
19271         local dircnt=$($LFS find -H fnv_1a_64 $DIR/$tdir/hashdir | wc -l)
19272         [ $dircnt -eq 1 ] || error "lfs find striped dir got:$dircnt,except:1"
19273
19274         #set the stripe to be unknown hash type
19275         #define OBD_FAIL_UNKNOWN_LMV_STRIPE     0x1901
19276         $LCTL set_param fail_loc=0x1901
19277         for ((i = 0; i < 10; i++)); do
19278                 $CHECKSTAT -t file $DIR/$tdir/striped_dir/f-$i ||
19279                         error "stat f-$i failed"
19280                 rm $DIR/$tdir/striped_dir/f-$i || error "unlink f-$i failed"
19281         done
19282
19283         touch $DIR/$tdir/striped_dir/f0 &&
19284                 error "create under striped dir with unknown hash should fail"
19285
19286         $LCTL set_param fail_loc=0
19287
19288         umount_client $MOUNT || error "umount failed"
19289         mount_client $MOUNT || error "mount failed"
19290
19291         return 0
19292 }
19293 run_test 300i "client handle unknown hash type striped directory"
19294
19295 test_300j() {
19296         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19297         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19298         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19299                 skip "Need MDS version at least 2.7.55"
19300
19301         local stripe_count
19302         local file
19303
19304         mkdir $DIR/$tdir
19305
19306         #define OBD_FAIL_SPLIT_UPDATE_REC       0x1702
19307         $LCTL set_param fail_loc=0x1702
19308         $LFS setdirstripe -i 0 -c$MDSCOUNT -H all_char $DIR/$tdir/striped_dir ||
19309                 error "set striped dir error"
19310
19311         createmany -o $DIR/$tdir/striped_dir/f- 10 ||
19312                 error "create files under striped dir failed"
19313
19314         $LCTL set_param fail_loc=0
19315
19316         rm -rf $DIR/$tdir || error "unlink striped dir fails"
19317
19318         return 0
19319 }
19320 run_test 300j "test large update record"
19321
19322 test_300k() {
19323         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19324         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19325         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19326                 skip "Need MDS version at least 2.7.55"
19327
19328         # this test needs a huge transaction
19329         local kb
19330         kb=$(do_facet $SINGLEMDS lctl get_param -n osd*.lustre-MDT0000.kbytestotal)
19331         [ $kb -lt $((1024*1024)) ] && skip "too small mds: $kb"
19332
19333         local stripe_count
19334         local file
19335
19336         mkdir $DIR/$tdir
19337
19338         #define OBD_FAIL_LARGE_STRIPE   0x1703
19339         $LCTL set_param fail_loc=0x1703
19340         $LFS setdirstripe -i 0 -c192 $DIR/$tdir/striped_dir ||
19341                 error "set striped dir error"
19342         $LCTL set_param fail_loc=0
19343
19344         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19345                 error "getstripeddir fails"
19346         rm -rf $DIR/$tdir/striped_dir ||
19347                 error "unlink striped dir fails"
19348
19349         return 0
19350 }
19351 run_test 300k "test large striped directory"
19352
19353 test_300l() {
19354         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19355         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19356         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19357                 skip "Need MDS version at least 2.7.55"
19358
19359         local stripe_index
19360
19361         test_mkdir -p $DIR/$tdir/striped_dir
19362         chown $RUNAS_ID $DIR/$tdir/striped_dir ||
19363                         error "chown $RUNAS_ID failed"
19364         $LFS setdirstripe -i 1 -D $DIR/$tdir/striped_dir ||
19365                 error "set default striped dir failed"
19366
19367         #define OBD_FAIL_MDS_STALE_DIR_LAYOUT    0x158
19368         $LCTL set_param fail_loc=0x80000158
19369         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir || error "create dir fails"
19370
19371         stripe_index=$($LFS getdirstripe -i $DIR/$tdir/striped_dir/test_dir)
19372         [ $stripe_index -eq 1 ] ||
19373                 error "expect 1 get $stripe_index for $dir"
19374 }
19375 run_test 300l "non-root user to create dir under striped dir with stale layout"
19376
19377 test_300m() {
19378         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19379         [ $MDSCOUNT -ge 2 ] && skip_env "Only for single MDT"
19380         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19381                 skip "Need MDS version at least 2.7.55"
19382
19383         mkdir -p $DIR/$tdir/striped_dir
19384         $LFS setdirstripe -D -c 1 $DIR/$tdir/striped_dir ||
19385                 error "set default stripes dir error"
19386
19387         mkdir $DIR/$tdir/striped_dir/a || error "mkdir a fails"
19388
19389         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/a)
19390         [ $stripe_count -eq 0 ] ||
19391                         error "expect 0 get $stripe_count for a"
19392
19393         $LFS setdirstripe -D -c 2 $DIR/$tdir/striped_dir ||
19394                 error "set default stripes dir error"
19395
19396         mkdir $DIR/$tdir/striped_dir/b || error "mkdir b fails"
19397
19398         stripe_count=$($LFS getdirstripe -c $DIR/$tdir/striped_dir/b)
19399         [ $stripe_count -eq 0 ] ||
19400                         error "expect 0 get $stripe_count for b"
19401
19402         $LFS setdirstripe -D -c1 -i2 $DIR/$tdir/striped_dir ||
19403                 error "set default stripes dir error"
19404
19405         mkdir $DIR/$tdir/striped_dir/c &&
19406                 error "default stripe_index is invalid, mkdir c should fails"
19407
19408         rm -rf $DIR/$tdir || error "rmdir fails"
19409 }
19410 run_test 300m "setstriped directory on single MDT FS"
19411
19412 cleanup_300n() {
19413         local list=$(comma_list $(mdts_nodes))
19414
19415         trap 0
19416         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19417 }
19418
19419 test_300n() {
19420         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19421         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19422         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19423                 skip "Need MDS version at least 2.7.55"
19424         remote_mds_nodsh && skip "remote MDS with nodsh"
19425
19426         local stripe_index
19427         local list=$(comma_list $(mdts_nodes))
19428
19429         trap cleanup_300n RETURN EXIT
19430         mkdir -p $DIR/$tdir
19431         chmod 777 $DIR/$tdir
19432         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT \
19433                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19434                 error "create striped dir succeeds with gid=0"
19435
19436         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19437         $RUNAS $LFS setdirstripe -i0 -c$MDSCOUNT $DIR/$tdir/striped_dir ||
19438                 error "create striped dir fails with gid=-1"
19439
19440         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19441         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D \
19442                                 $DIR/$tdir/striped_dir > /dev/null 2>&1 &&
19443                 error "set default striped dir succeeds with gid=0"
19444
19445
19446         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=-1
19447         $RUNAS $LFS setdirstripe -i 1 -c$MDSCOUNT -D $DIR/$tdir/striped_dir ||
19448                 error "set default striped dir fails with gid=-1"
19449
19450
19451         do_nodes $list $LCTL set_param -n mdt.*.enable_remote_dir_gid=0
19452         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir ||
19453                                         error "create test_dir fails"
19454         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir1 ||
19455                                         error "create test_dir1 fails"
19456         $RUNAS mkdir $DIR/$tdir/striped_dir/test_dir2 ||
19457                                         error "create test_dir2 fails"
19458         cleanup_300n
19459 }
19460 run_test 300n "non-root user to create dir under striped dir with default EA"
19461
19462 test_300o() {
19463         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19464         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19465         [ $MDS1_VERSION -lt $(version_code 2.7.55) ] &&
19466                 skip "Need MDS version at least 2.7.55"
19467
19468         local numfree1
19469         local numfree2
19470
19471         mkdir -p $DIR/$tdir
19472
19473         numfree1=$(lctl get_param -n mdc.*MDT0000*.filesfree)
19474         numfree2=$(lctl get_param -n mdc.*MDT0001*.filesfree)
19475         if [ $numfree1 -lt 66000 ] || [ $numfree2 -lt 66000 ]; then
19476                 skip "not enough free inodes $numfree1 $numfree2"
19477         fi
19478
19479         numfree1=$(lctl get_param -n mdc.*MDT0000-mdc-*.kbytesfree)
19480         numfree2=$(lctl get_param -n mdc.*MDT0001-mdc-*.kbytesfree)
19481         if [ $numfree1 -lt 300000 ] || [ $numfree2 -lt 300000 ]; then
19482                 skip "not enough free space $numfree1 $numfree2"
19483         fi
19484
19485         $LFS setdirstripe -c2 $DIR/$tdir/striped_dir ||
19486                 error "setdirstripe fails"
19487
19488         createmany -d $DIR/$tdir/striped_dir/d 131000 ||
19489                 error "create dirs fails"
19490
19491         $LCTL set_param ldlm.namespaces.*mdc-*.lru_size=0
19492         ls $DIR/$tdir/striped_dir > /dev/null ||
19493                 error "ls striped dir fails"
19494         unlinkmany -d $DIR/$tdir/striped_dir/d 131000 ||
19495                 error "unlink big striped dir fails"
19496 }
19497 run_test 300o "unlink big sub stripe(> 65000 subdirs)"
19498
19499 test_300p() {
19500         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19501         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19502         remote_mds_nodsh && skip "remote MDS with nodsh"
19503
19504         mkdir -p $DIR/$tdir
19505
19506         #define OBD_FAIL_OUT_ENOSPC     0x1704
19507         do_facet mds2 lctl set_param fail_loc=0x80001704
19508         $LFS setdirstripe -i 0 -c2 $DIR/$tdir/bad_striped_dir > /dev/null 2>&1 \
19509                  && error "create striped directory should fail"
19510
19511         [ -e $DIR/$tdir/bad_striped_dir ] && error "striped dir exists"
19512
19513         $LFS setdirstripe -c2 $DIR/$tdir/bad_striped_dir
19514         true
19515 }
19516 run_test 300p "create striped directory without space"
19517
19518 test_300q() {
19519         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19520         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
19521
19522         local fd=$(free_fd)
19523         local cmd="exec $fd<$tdir"
19524         cd $DIR
19525         $LFS mkdir -c $MDSCOUNT $tdir || error "create $tdir fails"
19526         eval $cmd
19527         cmd="exec $fd<&-"
19528         trap "eval $cmd" EXIT
19529         cd $tdir || error "cd $tdir fails"
19530         rmdir  ../$tdir || error "rmdir $tdir fails"
19531         mkdir local_dir && error "create dir succeeds"
19532         $LFS setdirstripe -i1 remote_dir && error "create remote dir succeeds"
19533         eval $cmd
19534         return 0
19535 }
19536 run_test 300q "create remote directory under orphan directory"
19537
19538 test_300r() {
19539         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.7.55) ] &&
19540                 skip "Need MDS version at least 2.7.55" && return
19541         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return
19542
19543         mkdir $DIR/$tdir
19544
19545         $LFS setdirstripe -i 0 -c -1 $DIR/$tdir/striped_dir ||
19546                 error "set striped dir error"
19547
19548         $LFS getdirstripe $DIR/$tdir/striped_dir ||
19549                 error "getstripeddir fails"
19550
19551         local stripe_count
19552         stripe_count=$($LFS getdirstripe $DIR/$tdir/striped_dir |
19553                       awk '/lmv_stripe_count:/ { print $2 }')
19554
19555         [ $MDSCOUNT -ne $stripe_count ] &&
19556                 error "wrong stripe count $stripe_count expected $MDSCOUNT"
19557
19558         rm -rf $DIR/$tdir/striped_dir ||
19559                 error "unlink striped dir fails"
19560 }
19561 run_test 300r "test -1 striped directory"
19562
19563 prepare_remote_file() {
19564         mkdir $DIR/$tdir/src_dir ||
19565                 error "create remote source failed"
19566
19567         cp /etc/hosts $DIR/$tdir/src_dir/a ||
19568                  error "cp to remote source failed"
19569         touch $DIR/$tdir/src_dir/a
19570
19571         $LFS mkdir -i 1 $DIR/$tdir/tgt_dir ||
19572                 error "create remote target dir failed"
19573
19574         touch $DIR/$tdir/tgt_dir/b
19575
19576         mrename $DIR/$tdir/src_dir/a $DIR/$tdir/tgt_dir/b ||
19577                 error "rename dir cross MDT failed!"
19578
19579         $CHECKSTAT -t file $DIR/$tdir/src_dir/a &&
19580                 error "src_child still exists after rename"
19581
19582         $CHECKSTAT -t file $DIR/$tdir/tgt_dir/b ||
19583                 error "missing file(a) after rename"
19584
19585         diff /etc/hosts $DIR/$tdir/tgt_dir/b ||
19586                 error "diff after rename"
19587 }
19588
19589 test_310a() {
19590         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19591         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19592
19593         local remote_file=$DIR/$tdir/tgt_dir/b
19594
19595         mkdir -p $DIR/$tdir
19596
19597         prepare_remote_file || error "prepare remote file failed"
19598
19599         #open-unlink file
19600         $OPENUNLINK $remote_file $remote_file ||
19601                 error "openunlink $remote_file failed"
19602         $CHECKSTAT -a $remote_file || error "$remote_file exists"
19603 }
19604 run_test 310a "open unlink remote file"
19605
19606 test_310b() {
19607         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 4 MDTs"
19608         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19609
19610         local remote_file=$DIR/$tdir/tgt_dir/b
19611
19612         mkdir -p $DIR/$tdir
19613
19614         prepare_remote_file || error "prepare remote file failed"
19615
19616         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19617         $MULTIOP $DIR/$tfile Ouc || error "mulitop failed"
19618         $CHECKSTAT -t file $remote_file || error "check file failed"
19619 }
19620 run_test 310b "unlink remote file with multiple links while open"
19621
19622 test_310c() {
19623         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19624         [[ $MDSCOUNT -lt 4 ]] && skip_env "needs >= 4 MDTs"
19625
19626         local remote_file=$DIR/$tdir/tgt_dir/b
19627
19628         mkdir -p $DIR/$tdir
19629
19630         prepare_remote_file || error "prepare remote file failed"
19631
19632         ln $remote_file $DIR/$tfile || error "link failed for remote file"
19633         multiop_bg_pause $remote_file O_uc ||
19634                         error "mulitop failed for remote file"
19635         MULTIPID=$!
19636         $MULTIOP $DIR/$tfile Ouc
19637         kill -USR1 $MULTIPID
19638         wait $MULTIPID
19639 }
19640 run_test 310c "open-unlink remote file with multiple links"
19641
19642 #LU-4825
19643 test_311() {
19644         [ $PARALLEL == "yes" ] && skip "skip parallel run"
19645         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19646         [ $MDS1_VERSION -lt $(version_code 2.8.54) ] &&
19647                 skip "lustre < 2.8.54 does not contain LU-4825 fix"
19648         remote_mds_nodsh && skip "remote MDS with nodsh"
19649
19650         local old_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19651         local mdts=$(comma_list $(mdts_nodes))
19652
19653         mkdir -p $DIR/$tdir
19654         $LFS setstripe -i 0 -c 1 $DIR/$tdir
19655         createmany -o $DIR/$tdir/$tfile. 1000
19656
19657         # statfs data is not real time, let's just calculate it
19658         old_iused=$((old_iused + 1000))
19659
19660         local count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19661                         osp.*OST0000*MDT0000.create_count")
19662         local max_count=$(do_facet $SINGLEMDS "$LCTL get_param -n \
19663                                 osp.*OST0000*MDT0000.max_create_count")
19664         do_nodes $mdts "$LCTL set_param -n osp.*OST0000*.max_create_count=0"
19665
19666         $LFS setstripe -i 0 $DIR/$tdir/$tfile || error "setstripe failed"
19667         local index=$($LFS getstripe -i $DIR/$tdir/$tfile)
19668         [ $index -ne 0 ] || error "$tfile stripe index is 0"
19669
19670         unlinkmany $DIR/$tdir/$tfile. 1000
19671
19672         do_nodes $mdts "$LCTL set_param -n \
19673                         osp.*OST0000*.max_create_count=$max_count"
19674         [ $MDS1_VERSION -lt $(version_code 2.12.51) ] &&
19675                 do_nodes $mdts "$LCTL set_param -n \
19676                                 osp.*OST0000*.create_count=$count"
19677         do_nodes $mdts "$LCTL get_param osp.*OST0000*.create_count" |
19678                         grep "=0" && error "create_count is zero"
19679
19680         local new_iused
19681         for i in $(seq 120); do
19682                 new_iused=$($LFS df -i | grep OST0000 | awk '{ print $3 }')
19683                 # system may be too busy to destroy all objs in time, use
19684                 # a somewhat small value to not fail autotest
19685                 [ $((old_iused - new_iused)) -gt 400 ] && break
19686                 sleep 1
19687         done
19688
19689         echo "waited $i sec, old Iused $old_iused, new Iused $new_iused"
19690         [ $((old_iused - new_iused)) -gt 400 ] ||
19691                 error "objs not destroyed after unlink"
19692 }
19693 run_test 311 "disable OSP precreate, and unlink should destroy objs"
19694
19695 zfs_oid_to_objid()
19696 {
19697         local ost=$1
19698         local objid=$2
19699
19700         local vdevdir=$(dirname $(facet_vdevice $ost))
19701         local cmd="$ZDB -e -p $vdevdir -ddddd $(facet_device $ost)"
19702         local zfs_zapid=$(do_facet $ost $cmd |
19703                           grep -w "/O/0/d$((objid%32))" -C 5 |
19704                           awk '/Object/{getline; print $1}')
19705         local zfs_objid=$(do_facet $ost $cmd $zfs_zapid |
19706                           awk "/$objid = /"'{printf $3}')
19707
19708         echo $zfs_objid
19709 }
19710
19711 zfs_object_blksz() {
19712         local ost=$1
19713         local objid=$2
19714
19715         local vdevdir=$(dirname $(facet_vdevice $ost))
19716         local cmd="$ZDB -e -p $vdevdir -dddd $(facet_device $ost)"
19717         local blksz=$(do_facet $ost $cmd $objid |
19718                       awk '/dblk/{getline; printf $4}')
19719
19720         case "${blksz: -1}" in
19721                 k|K) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024)) ;;
19722                 m|M) blksz=$((${blksz:0:$((${#blksz} - 1))}*1024*1024)) ;;
19723                 *) ;;
19724         esac
19725
19726         echo $blksz
19727 }
19728
19729 test_312() { # LU-4856
19730         remote_ost_nodsh && skip "remote OST with nodsh"
19731         [ "$ost1_FSTYPE" = "zfs" ] ||
19732                 skip_env "the test only applies to zfs"
19733
19734         local max_blksz=$(do_facet ost1 \
19735                           $ZFS get -p recordsize $(facet_device ost1) |
19736                           awk '!/VALUE/{print $3}')
19737
19738         # to make life a little bit easier
19739         $LFS mkdir -c 1 -i 0 $DIR/$tdir
19740         $LFS setstripe -c 1 -i 0 $DIR/$tdir
19741
19742         local tf=$DIR/$tdir/$tfile
19743         touch $tf
19744         local oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19745
19746         # Get ZFS object id
19747         local zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19748         # block size change by sequential overwrite
19749         local bs
19750
19751         for ((bs=$PAGE_SIZE; bs <= max_blksz; bs *= 4)) ; do
19752                 dd if=/dev/zero of=$tf bs=$bs count=1 oflag=sync conv=notrunc
19753
19754                 local blksz=$(zfs_object_blksz ost1 $zfs_objid)
19755                 [ $blksz -eq $bs ] || error "blksz error: $blksz, expected: $bs"
19756         done
19757         rm -f $tf
19758
19759         # block size change by sequential append write
19760         dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=1 oflag=sync conv=notrunc
19761         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19762         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19763         local count
19764
19765         for ((count = 1; count < $((max_blksz / PAGE_SIZE)); count *= 2)); do
19766                 dd if=/dev/zero of=$tf bs=$PAGE_SIZE count=$count seek=$count \
19767                         oflag=sync conv=notrunc
19768
19769                 blksz=$(zfs_object_blksz ost1 $zfs_objid)
19770                 [ $blksz -eq $((2 * count * PAGE_SIZE)) ] ||
19771                         error "blksz error, actual $blksz, " \
19772                                 "expected: 2 * $count * $PAGE_SIZE"
19773         done
19774         rm -f $tf
19775
19776         # random write
19777         touch $tf
19778         oid=$($LFS getstripe $tf | awk '/obdidx/{getline; print $2}')
19779         zfs_objid=$(zfs_oid_to_objid ost1 $oid)
19780
19781         dd if=/dev/zero of=$tf bs=1K count=1 oflag=sync conv=notrunc
19782         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19783         [ $blksz -eq $PAGE_SIZE ] ||
19784                 error "blksz error: $blksz, expected: $PAGE_SIZE"
19785
19786         dd if=/dev/zero of=$tf bs=64K count=1 oflag=sync conv=notrunc seek=128
19787         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19788         [ $blksz -eq 65536 ] || error "blksz error: $blksz, expected: 64k"
19789
19790         dd if=/dev/zero of=$tf bs=1M count=1 oflag=sync conv=notrunc
19791         blksz=$(zfs_object_blksz ost1 $zfs_objid)
19792         [ $blksz -eq 65536 ] || error "rewrite error: $blksz, expected: 64k"
19793 }
19794 run_test 312 "make sure ZFS adjusts its block size by write pattern"
19795
19796 test_313() {
19797         remote_ost_nodsh && skip "remote OST with nodsh"
19798
19799         local file=$DIR/$tfile
19800
19801         rm -f $file
19802         $LFS setstripe -c 1 -i 0 $file || error "setstripe failed"
19803
19804         # define OBD_FAIL_TGT_RCVD_EIO           0x720
19805         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19806         dd if=/dev/zero of=$file bs=$PAGE_SIZE oflag=direct count=1 &&
19807                 error "write should failed"
19808         do_facet ost1 "$LCTL set_param fail_loc=0"
19809         rm -f $file
19810 }
19811 run_test 313 "io should fail after last_rcvd update fail"
19812
19813 test_314() {
19814         [ $OSTCOUNT -lt 2 ] && skip "needs >= 2 OSTs"
19815
19816         $LFS setstripe -c 2 -i 0 $DIR/$tfile || error "setstripe failed"
19817         do_facet ost1 "$LCTL set_param fail_loc=0x720"
19818         rm -f $DIR/$tfile
19819         wait_delete_completed
19820         do_facet ost1 "$LCTL set_param fail_loc=0"
19821 }
19822 run_test 314 "OSP shouldn't fail after last_rcvd update failure"
19823
19824 test_315() { # LU-618
19825         [ -f /proc/$$/io ] || skip_env "no IO accounting in kernel"
19826
19827         local file=$DIR/$tfile
19828         rm -f $file
19829
19830         $MULTIOP $file oO_CREAT:O_DIRECT:O_RDWR:w4063232c ||
19831                 error "multiop file write failed"
19832         $MULTIOP $file oO_RDONLY:r4063232_c &
19833         PID=$!
19834
19835         sleep 2
19836
19837         local rbytes=$(awk '/read_bytes/ { print $2 }' /proc/$PID/io)
19838         kill -USR1 $PID
19839
19840         [ $rbytes -gt 4000000 ] || error "read is not accounted ($rbytes)"
19841         rm -f $file
19842 }
19843 run_test 315 "read should be accounted"
19844
19845 test_316() {
19846         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
19847         large_xattr_enabled || skip_env "ea_inode feature disabled"
19848
19849         rm -rf $DIR/$tdir/d
19850         mkdir -p $DIR/$tdir/d
19851         chown nobody $DIR/$tdir/d
19852         touch $DIR/$tdir/d/file
19853
19854         $LFS mv -M1 $DIR/$tdir/d || error "lfs mv failed"
19855 }
19856 run_test 316 "lfs mv"
19857
19858 test_317() {
19859         [ $MDS1_VERSION -lt $(version_code 2.11.53) ] &&
19860                 skip "Need MDS version at least 2.11.53"
19861         if [ "$ost1_FSTYPE" == "zfs" ]; then
19862                 skip "LU-10370: no implementation for ZFS"
19863         fi
19864
19865         local trunc_sz
19866         local grant_blk_size
19867
19868         grant_blk_size=$($LCTL get_param osc.$FSNAME*.import |
19869                         awk '/grant_block_size:/ { print $2; exit; }')
19870         #
19871         # Create File of size 5M. Truncate it to below size's and verify
19872         # blocks count.
19873         #
19874         dd if=/dev/zero of=$DIR/$tfile bs=5M count=1 conv=fsync ||
19875                 error "Create file $DIR/$tfile failed"
19876         stack_trap "rm -f $DIR/$tfile" EXIT
19877
19878         for trunc_sz in 2097152 4097 4000 509 0; do
19879                 $TRUNCATE $DIR/$tfile $trunc_sz ||
19880                         error "truncate $tfile to $trunc_sz failed"
19881                 local sz=$(stat --format=%s $DIR/$tfile)
19882                 local blk=$(stat --format=%b $DIR/$tfile)
19883                 local trunc_blk=$((((trunc_sz + (grant_blk_size - 1) ) /
19884                                      grant_blk_size) * 8))
19885
19886                 if [[ $blk -ne $trunc_blk ]]; then
19887                         $(which stat) $DIR/$tfile
19888                         error "Expected Block $trunc_blk got $blk for $tfile"
19889                 fi
19890
19891                 $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19892                         error "Expected Size $trunc_sz got $sz for $tfile"
19893         done
19894
19895         #
19896         # sparse file test
19897         # Create file with a hole and write actual two blocks. Block count
19898         # must be 16.
19899         #
19900         dd if=/dev/zero of=$DIR/$tfile bs=$grant_blk_size count=2 seek=5 \
19901                 conv=fsync || error "Create file : $DIR/$tfile"
19902
19903         # Calculate the final truncate size.
19904         trunc_sz=$(($(stat --format=%s $DIR/$tfile) - (grant_blk_size + 1)))
19905
19906         #
19907         # truncate to size $trunc_sz bytes. Strip the last block
19908         # The block count must drop to 8
19909         #
19910         $TRUNCATE $DIR/$tfile $trunc_sz ||
19911                 error "truncate $tfile to $trunc_sz failed"
19912
19913         local trunc_bsz=$((grant_blk_size / $(stat --format=%B $DIR/$tfile)))
19914         sz=$(stat --format=%s $DIR/$tfile)
19915         blk=$(stat --format=%b $DIR/$tfile)
19916
19917         if [[ $blk -ne $trunc_bsz ]]; then
19918                 $(which stat) $DIR/$tfile
19919                 error "Expected Block $trunc_bsz got $blk for $tfile"
19920         fi
19921
19922         $CHECKSTAT -s $trunc_sz $DIR/$tfile ||
19923                 error "Expected Size $trunc_sz got $sz for $tfile"
19924 }
19925 run_test 317 "Verify blocks get correctly update after truncate"
19926
19927 test_318() {
19928         local old_max_active=$($LCTL get_param -n \
19929                             llite.*.max_read_ahead_async_active 2>/dev/null)
19930
19931         $LCTL set_param llite.*.max_read_ahead_async_active=256
19932         local max_active=$($LCTL get_param -n \
19933                            llite.*.max_read_ahead_async_active 2>/dev/null)
19934         [ $max_active -ne 256 ] && error "expected 256 but got $max_active"
19935
19936         # currently reset to 0 is unsupported, leave it 512 for now.
19937         $LCTL set_param llite.*.max_read_ahead_async_active=0 &&
19938                 error "set max_read_ahead_async_active should fail"
19939
19940         $LCTL set_param llite.*.max_read_ahead_async_active=512
19941         max_active=$($LCTL get_param -n \
19942                      llite.*.max_read_ahead_async_active 2>/dev/null)
19943         [ $max_active -eq 512 ] || error "expected 512 but got $max_active"
19944
19945         # restore @max_active
19946         [ $old_max_active -ne 0 ] && $LCTL set_param \
19947                 llite.*.max_read_ahead_async_active=$old_max_active
19948
19949         local old_threshold=$($LCTL get_param -n \
19950                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19951         local max_per_file_mb=$($LCTL get_param -n \
19952                 llite.*.max_read_ahead_per_file_mb 2>/dev/null)
19953
19954         local invalid=$(($max_per_file_mb + 1))
19955         $LCTL set_param \
19956                 llite.*.read_ahead_async_file_threshold_mb=$invalid\
19957                         && error "set $invalid should fail"
19958
19959         local valid=$(($invalid - 1))
19960         $LCTL set_param \
19961                 llite.*.read_ahead_async_file_threshold_mb=$valid ||
19962                         error "set $valid should succeed"
19963         local threshold=$($LCTL get_param -n \
19964                 llite.*.read_ahead_async_file_threshold_mb 2>/dev/null)
19965         [ $threshold -eq $valid ] || error \
19966                 "expect threshold $valid got $threshold"
19967         $LCTL set_param \
19968                 llite.*.read_ahead_async_file_threshold_mb=$old_threshold
19969 }
19970 run_test 318 "Verify async readahead tunables"
19971
19972 test_319() {
19973         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs" && return 0
19974
19975         local before=$(date +%s)
19976         local evict
19977         local mdir=$DIR/$tdir
19978         local file=$mdir/xxx
19979
19980         $LFS mkdir -i0 $mdir || error "mkdir $mdir fails"
19981         touch $file
19982
19983 #define OBD_FAIL_LDLM_LOCAL_CANCEL_PAUSE 0x32c
19984         $LCTL set_param fail_val=5 fail_loc=0x8000032c
19985         $LFS mv -m1 $file &
19986
19987         sleep 1
19988         dd if=$file of=/dev/null
19989         wait
19990         evict=$($LCTL get_param mdc.$FSNAME-MDT*.state |
19991           awk -F"[ [,]" '/EVICTED ]$/ { if (mx<$5) {mx=$5;} } END { print mx }')
19992
19993         [ -z "$evict" ] || [[ $evict -le $before ]] || error "eviction happened"
19994 }
19995 run_test 319 "lost lease lock on migrate error"
19996
19997 test_fake_rw() {
19998         local read_write=$1
19999         if [ "$read_write" = "write" ]; then
20000                 local dd_cmd="dd if=/dev/zero of=$DIR/$tfile"
20001         elif [ "$read_write" = "read" ]; then
20002                 local dd_cmd="dd of=/dev/null if=$DIR/$tfile"
20003         else
20004                 error "argument error"
20005         fi
20006
20007         # turn off debug for performance testing
20008         local saved_debug=$($LCTL get_param -n debug)
20009         $LCTL set_param debug=0
20010
20011         $LFS setstripe -c 1 -i 0 $DIR/$tfile
20012
20013         # get ost1 size - lustre-OST0000
20014         local ost1_avail_size=$($LFS df | awk /${ost1_svc}/'{ print $4 }')
20015         local blocks=$((ost1_avail_size/2/1024)) # half avail space by megabytes
20016         [ $blocks -gt 1000 ] && blocks=1000 # 1G in maximum
20017
20018         if [ "$read_write" = "read" ]; then
20019                 truncate -s $(expr 1048576 \* $blocks) $DIR/$tfile
20020         fi
20021
20022         local start_time=$(date +%s.%N)
20023         $dd_cmd bs=1M count=$blocks oflag=sync ||
20024                 error "real dd $read_write error"
20025         local duration=$(bc <<< "$(date +%s.%N) - $start_time")
20026
20027         if [ "$read_write" = "write" ]; then
20028                 rm -f $DIR/$tfile
20029         fi
20030
20031         # define OBD_FAIL_OST_FAKE_RW           0x238
20032         do_facet ost1 $LCTL set_param fail_loc=0x238
20033
20034         local start_time=$(date +%s.%N)
20035         $dd_cmd bs=1M count=$blocks oflag=sync ||
20036                 error "fake dd $read_write error"
20037         local duration_fake=$(bc <<< "$(date +%s.%N) - $start_time")
20038
20039         if [ "$read_write" = "write" ]; then
20040                 # verify file size
20041                 cancel_lru_locks osc
20042                 $CHECKSTAT -t file -s $((blocks * 1024 * 1024)) $DIR/$tfile ||
20043                         error "$tfile size not $blocks MB"
20044         fi
20045         do_facet ost1 $LCTL set_param fail_loc=0
20046
20047         echo "fake $read_write $duration_fake vs. normal $read_write" \
20048                 "$duration in seconds"
20049         [ $(bc <<< "$duration_fake < $duration") -eq 1 ] ||
20050                 error_not_in_vm "fake write is slower"
20051
20052         $LCTL set_param -n debug="$saved_debug"
20053         rm -f $DIR/$tfile
20054 }
20055 test_399a() { # LU-7655 for OST fake write
20056         remote_ost_nodsh && skip "remote OST with nodsh"
20057
20058         test_fake_rw write
20059 }
20060 run_test 399a "fake write should not be slower than normal write"
20061
20062 test_399b() { # LU-8726 for OST fake read
20063         remote_ost_nodsh && skip "remote OST with nodsh"
20064         if [ "$ost1_FSTYPE" != "ldiskfs" ]; then
20065                 skip_env "ldiskfs only test"
20066         fi
20067
20068         test_fake_rw read
20069 }
20070 run_test 399b "fake read should not be slower than normal read"
20071
20072 test_400a() { # LU-1606, was conf-sanity test_74
20073         if ! which $CC > /dev/null 2>&1; then
20074                 skip_env "$CC is not installed"
20075         fi
20076
20077         local extra_flags=''
20078         local out=$TMP/$tfile
20079         local prefix=/usr/include/lustre
20080         local prog
20081
20082         if ! [[ -d $prefix ]]; then
20083                 # Assume we're running in tree and fixup the include path.
20084                 extra_flags+=" -I$LUSTRE/../lnet/include/uapi -I$LUSTRE/include/uapi -I$LUSTRE/include"
20085                 extra_flags+=" -L$LUSTRE/utils/.lib"
20086         fi
20087
20088         for prog in $LUSTRE_TESTS_API_DIR/*.c; do
20089                 $CC -Wall -Werror $extra_flags -o $out $prog -llustreapi ||
20090                         error "client api broken"
20091         done
20092         rm -f $out
20093 }
20094 run_test 400a "Lustre client api program can compile and link"
20095
20096 test_400b() { # LU-1606, LU-5011
20097         local header
20098         local out=$TMP/$tfile
20099         local prefix=/usr/include/linux/lustre
20100
20101         # We use a hard coded prefix so that this test will not fail
20102         # when run in tree. There are headers in lustre/include/lustre/
20103         # that are not packaged (like lustre_idl.h) and have more
20104         # complicated include dependencies (like config.h and lnet/types.h).
20105         # Since this test about correct packaging we just skip them when
20106         # they don't exist (see below) rather than try to fixup cppflags.
20107
20108         if ! which $CC > /dev/null 2>&1; then
20109                 skip_env "$CC is not installed"
20110         fi
20111
20112         for header in $prefix/*.h; do
20113                 if ! [[ -f "$header" ]]; then
20114                         continue
20115                 fi
20116
20117                 if [[ "$(basename $header)" == lustre_ioctl.h ]]; then
20118                         continue # lustre_ioctl.h is internal header
20119                 fi
20120
20121                 $CC -Wall -Werror -include $header -c -x c /dev/null -o $out ||
20122                         error "cannot compile '$header'"
20123         done
20124         rm -f $out
20125 }
20126 run_test 400b "packaged headers can be compiled"
20127
20128 test_401a() { #LU-7437
20129         local printf_arg=$(find -printf 2>&1 | grep "unrecognized:")
20130         [ -n "$printf_arg" ] && skip_env "find does not support -printf"
20131
20132         #count the number of parameters by "list_param -R"
20133         local params=$($LCTL list_param -R '*' 2>/dev/null | wc -l)
20134         #count the number of parameters by listing proc files
20135         local proc_dirs=$(eval \ls -d $proc_regexp 2>/dev/null)
20136         echo "proc_dirs='$proc_dirs'"
20137         [ -n "$proc_dirs" ] || error "no proc_dirs on $HOSTNAME"
20138         local procs=$(find -L $proc_dirs -mindepth 1 -printf '%P\n' 2>/dev/null|
20139                       sort -u | wc -l)
20140
20141         [ $params -eq $procs ] ||
20142                 error "found $params parameters vs. $procs proc files"
20143
20144         # test the list_param -D option only returns directories
20145         params=$($LCTL list_param -R -D '*' 2>/dev/null | wc -l)
20146         #count the number of parameters by listing proc directories
20147         procs=$(find -L $proc_dirs -mindepth 1 -type d -printf '%P\n' 2>/dev/null |
20148                 sort -u | wc -l)
20149
20150         [ $params -eq $procs ] ||
20151                 error "found $params parameters vs. $procs proc files"
20152 }
20153 run_test 401a "Verify if 'lctl list_param -R' can list parameters recursively"
20154
20155 test_401b() {
20156         local save=$($LCTL get_param -n jobid_var)
20157         local tmp=testing
20158
20159         $LCTL set_param foo=bar jobid_var=$tmp bar=baz &&
20160                 error "no error returned when setting bad parameters"
20161
20162         local jobid_new=$($LCTL get_param -n foe jobid_var baz)
20163         [[ "$jobid_new" == "$tmp" ]] || error "jobid tmp $jobid_new != $tmp"
20164
20165         $LCTL set_param -n fog=bam jobid_var=$save bat=fog
20166         local jobid_old=$($LCTL get_param -n foe jobid_var bag)
20167         [[ "$jobid_old" == "$save" ]] || error "jobid new $jobid_old != $save"
20168 }
20169 run_test 401b "Verify 'lctl {get,set}_param' continue after error"
20170
20171 test_401c() {
20172         local jobid_var_old=$($LCTL get_param -n jobid_var)
20173         local jobid_var_new
20174
20175         $LCTL set_param jobid_var= &&
20176                 error "no error returned for 'set_param a='"
20177
20178         jobid_var_new=$($LCTL get_param -n jobid_var)
20179         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20180                 error "jobid_var was changed by setting without value"
20181
20182         $LCTL set_param jobid_var &&
20183                 error "no error returned for 'set_param a'"
20184
20185         jobid_var_new=$($LCTL get_param -n jobid_var)
20186         [[ "$jobid_var_old" == "$jobid_var_new" ]] ||
20187                 error "jobid_var was changed by setting without value"
20188 }
20189 run_test 401c "Verify 'lctl set_param' without value fails in either format."
20190
20191 test_401d() {
20192         local jobid_var_old=$($LCTL get_param -n jobid_var)
20193         local jobid_var_new
20194         local new_value="foo=bar"
20195
20196         $LCTL set_param jobid_var=$new_value ||
20197                 error "'set_param a=b' did not accept a value containing '='"
20198
20199         jobid_var_new=$($LCTL get_param -n jobid_var)
20200         [[ "$jobid_var_new" == "$new_value" ]] ||
20201                 error "'set_param a=b' failed on a value containing '='"
20202
20203         # Reset the jobid_var to test the other format
20204         $LCTL set_param jobid_var=$jobid_var_old
20205         jobid_var_new=$($LCTL get_param -n jobid_var)
20206         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20207                 error "failed to reset jobid_var"
20208
20209         $LCTL set_param jobid_var $new_value ||
20210                 error "'set_param a b' did not accept a value containing '='"
20211
20212         jobid_var_new=$($LCTL get_param -n jobid_var)
20213         [[ "$jobid_var_new" == "$new_value" ]] ||
20214                 error "'set_param a b' failed on a value containing '='"
20215
20216         $LCTL set_param jobid_var $jobid_var_old
20217         jobid_var_new=$($LCTL get_param -n jobid_var)
20218         [[ "$jobid_var_new" == "$jobid_var_old" ]] ||
20219                 error "failed to reset jobid_var"
20220 }
20221 run_test 401d "Verify 'lctl set_param' accepts values containing '='"
20222
20223 test_402() {
20224         [[ $MDS1_VERSION -ge $(version_code 2.7.66) ]] ||
20225         [[ $MDS1_VERSION -ge $(version_code 2.7.18.4) &&
20226                 $MDS1_VERSION -lt $(version_code 2.7.50) ]] ||
20227         [[ $MDS1_VERSION -ge $(version_code 2.7.2) &&
20228                 $MDS1_VERSION -lt $(version_code 2.7.11) ]] ||
20229                 skip "Need MDS version 2.7.2+ or 2.7.18.4+ or 2.7.66+"
20230         remote_mds_nodsh && skip "remote MDS with nodsh"
20231
20232         $LFS setdirstripe -i 0 $DIR/$tdir || error "setdirstripe -i 0 failed"
20233 #define OBD_FAIL_MDS_FLD_LOOKUP 0x15c
20234         do_facet mds1 "lctl set_param fail_loc=0x8000015c"
20235         touch $DIR/$tdir/$tfile && error "touch should fail with ENOENT" ||
20236                 echo "Touch failed - OK"
20237 }
20238 run_test 402 "Return ENOENT to lod_generate_and_set_lovea"
20239
20240 test_403() {
20241         local file1=$DIR/$tfile.1
20242         local file2=$DIR/$tfile.2
20243         local tfile=$TMP/$tfile
20244
20245         rm -f $file1 $file2 $tfile
20246
20247         touch $file1
20248         ln $file1 $file2
20249
20250         # 30 sec OBD_TIMEOUT in ll_getattr()
20251         # right before populating st_nlink
20252         $LCTL set_param fail_loc=0x80001409
20253         stat -c %h $file1 > $tfile &
20254
20255         # create an alias, drop all locks and reclaim the dentry
20256         < $file2
20257         cancel_lru_locks mdc
20258         cancel_lru_locks osc
20259         sysctl -w vm.drop_caches=2
20260
20261         wait
20262
20263         [ $(cat $tfile) -gt 0 ] || error "wrong nlink count: $(cat $tfile)"
20264
20265         rm -f $tfile $file1 $file2
20266 }
20267 run_test 403 "i_nlink should not drop to zero due to aliasing"
20268
20269 test_404() { # LU-6601
20270         [[ $MDS1_VERSION -ge $(version_code 2.8.53) ]] ||
20271                 skip "Need server version newer than 2.8.52"
20272         remote_mds_nodsh && skip "remote MDS with nodsh"
20273
20274         local mosps=$(do_facet $SINGLEMDS $LCTL dl |
20275                 awk '/osp .*-osc-MDT/ { print $4}')
20276
20277         local osp
20278         for osp in $mosps; do
20279                 echo "Deactivate: " $osp
20280                 do_facet $SINGLEMDS $LCTL --device %$osp deactivate
20281                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20282                         awk -vp=$osp '$4 == p { print $2 }')
20283                 [ $stat = IN ] || {
20284                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20285                         error "deactivate error"
20286                 }
20287                 echo "Activate: " $osp
20288                 do_facet $SINGLEMDS $LCTL --device %$osp activate
20289                 local stat=$(do_facet $SINGLEMDS $LCTL dl |
20290                         awk -vp=$osp '$4 == p { print $2 }')
20291                 [ $stat = UP ] || {
20292                         do_facet $SINGLEMDS $LCTL dl | grep -w $osp
20293                         error "activate error"
20294                 }
20295         done
20296 }
20297 run_test 404 "validate manual {de}activated works properly for OSPs"
20298
20299 test_405() {
20300         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
20301         [ $MDS1_VERSION -lt $(version_code 2.6.92) ] ||
20302                 [ $CLIENT_VERSION -lt $(version_code 2.6.99) ] &&
20303                         skip "Layout swap lock is not supported"
20304
20305         check_swap_layouts_support
20306
20307         test_mkdir $DIR/$tdir
20308         swap_lock_test -d $DIR/$tdir ||
20309                 error "One layout swap locked test failed"
20310 }
20311 run_test 405 "Various layout swap lock tests"
20312
20313 test_406() {
20314         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20315         [ $OSTCOUNT -lt 2 ] && skip_env "needs >= 2 OSTs"
20316         [ -n "$FILESET" ] && skip "SKIP due to FILESET set"
20317         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20318         [ $MDS1_VERSION -lt $(version_code 2.8.50) ] &&
20319                 skip "Need MDS version at least 2.8.50"
20320
20321         local def_stripe_size=$($LFS getstripe -S $MOUNT)
20322         local test_pool=$TESTNAME
20323
20324         if ! combined_mgs_mds ; then
20325                 mount_mgs_client
20326         fi
20327         pool_add $test_pool || error "pool_add failed"
20328         pool_add_targets $test_pool 0 $(($OSTCOUNT - 1)) 1 ||
20329                 error "pool_add_targets failed"
20330
20331         save_layout_restore_at_exit $MOUNT
20332
20333         # parent set default stripe count only, child will stripe from both
20334         # parent and fs default
20335         $LFS setstripe -c 1 -i 1 -S $((def_stripe_size * 2)) -p $test_pool $MOUNT ||
20336                 error "setstripe $MOUNT failed"
20337         $LFS mkdir -c $MDSCOUNT $DIR/$tdir || error "mkdir $tdir failed"
20338         $LFS setstripe -c $OSTCOUNT $DIR/$tdir || error "setstripe $tdir failed"
20339         for i in $(seq 10); do
20340                 local f=$DIR/$tdir/$tfile.$i
20341                 touch $f || error "touch failed"
20342                 local count=$($LFS getstripe -c $f)
20343                 [ $count -eq $OSTCOUNT ] ||
20344                         error "$f stripe count $count != $OSTCOUNT"
20345                 local offset=$($LFS getstripe -i $f)
20346                 [ $offset -eq 1 ] || error "$f stripe offset $offset != 1"
20347                 local size=$($LFS getstripe -S $f)
20348                 [ $size -eq $((def_stripe_size * 2)) ] ||
20349                         error "$f stripe size $size != $((def_stripe_size * 2))"
20350                 local pool=$($LFS getstripe -p $f)
20351                 [ $pool == $test_pool ] || error "$f pool $pool != $test_pool"
20352         done
20353
20354         # change fs default striping, delete parent default striping, now child
20355         # will stripe from new fs default striping only
20356         $LFS setstripe -c 1 -S $def_stripe_size -i 0 $MOUNT ||
20357                 error "change $MOUNT default stripe failed"
20358         $LFS setstripe -c 0 $DIR/$tdir ||
20359                 error "delete $tdir default stripe failed"
20360         for i in $(seq 11 20); do
20361                 local f=$DIR/$tdir/$tfile.$i
20362                 touch $f || error "touch $f failed"
20363                 local count=$($LFS getstripe -c $f)
20364                 [ $count -eq 1 ] || error "$f stripe count $count != 1"
20365                 local offset=$($LFS getstripe -i $f)
20366                 [ $offset -eq 0 ] || error "$f stripe offset $offset != 0"
20367                 local size=$($LFS getstripe -S $f)
20368                 [ $size -eq $def_stripe_size ] ||
20369                         error "$f stripe size $size != $def_stripe_size"
20370                 local pool=$($LFS getstripe -p $f)
20371                 [ $pool == $test_pool ] || error "$f pool $pool isn't set"
20372         done
20373
20374         unlinkmany $DIR/$tdir/$tfile. 1 20
20375
20376         local f=$DIR/$tdir/$tfile
20377         pool_remove_all_targets $test_pool $f
20378         pool_remove $test_pool $f
20379
20380         if ! combined_mgs_mds ; then
20381                 umount_mgs_client
20382         fi
20383 }
20384 run_test 406 "DNE support fs default striping"
20385
20386 test_407() {
20387         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20388         [[ $MDS1_VERSION -lt $(version_code 2.8.55) ]] &&
20389                 skip "Need MDS version at least 2.8.55"
20390         remote_mds_nodsh && skip "remote MDS with nodsh"
20391
20392         $LFS mkdir -i 0 -c 1 $DIR/$tdir.0 ||
20393                 error "$LFS mkdir -i 0 -c 1 $tdir.0 failed"
20394         $LFS mkdir -i 1 -c 1 $DIR/$tdir.1 ||
20395                 error "$LFS mkdir -i 1 -c 1 $tdir.1 failed"
20396         touch $DIR/$tdir.0/$tfile.0 || error "touch $tdir.0/$tfile.0 failed"
20397
20398         #define OBD_FAIL_DT_TXN_STOP    0x2019
20399         for idx in $(seq $MDSCOUNT); do
20400                 do_facet mds$idx "lctl set_param fail_loc=0x2019"
20401         done
20402         $LFS mkdir -c 2 $DIR/$tdir && error "$LFS mkdir -c 2 $tdir should fail"
20403         mv $DIR/$tdir.0/$tfile.0 $DIR/$tdir.1/$tfile.1 &&
20404                 error "mv $tdir.0/$tfile.0 $tdir.1/$tfile.1 should fail"
20405         true
20406 }
20407 run_test 407 "transaction fail should cause operation fail"
20408
20409 test_408() {
20410         dd if=/dev/zero of=$DIR/$tfile bs=$PAGE_SIZE count=1 oflag=direct
20411
20412         #define OBD_FAIL_OSC_BRW_PREP_REQ2        0x40a
20413         lctl set_param fail_loc=0x8000040a
20414         # let ll_prepare_partial_page() fail
20415         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 conv=notrunc || true
20416
20417         rm -f $DIR/$tfile
20418
20419         # create at least 100 unused inodes so that
20420         # shrink_icache_memory(0) should not return 0
20421         touch $DIR/$tfile-{0..100}
20422         rm -f $DIR/$tfile-{0..100}
20423         sync
20424
20425         echo 2 > /proc/sys/vm/drop_caches
20426 }
20427 run_test 408 "drop_caches should not hang due to page leaks"
20428
20429 test_409()
20430 {
20431         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20432
20433         mkdir -p $DIR/$tdir || error "(0) Fail to mkdir"
20434         $LFS mkdir -i 1 -c 2 $DIR/$tdir/foo || error "(1) Fail to mkdir"
20435         touch $DIR/$tdir/guard || error "(2) Fail to create"
20436
20437         local PREFIX=$(str_repeat 'A' 128)
20438         echo "Create 1K hard links start at $(date)"
20439         createmany -l $DIR/$tdir/guard $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20440                 error "(3) Fail to hard link"
20441
20442         echo "Links count should be right although linkEA overflow"
20443         stat $DIR/$tdir/guard || error "(4) Fail to stat"
20444         local linkcount=$(stat --format=%h $DIR/$tdir/guard)
20445         [ $linkcount -eq 1001 ] ||
20446                 error "(5) Unexpected hard links count: $linkcount"
20447
20448         echo "List all links start at $(date)"
20449         ls -l $DIR/$tdir/foo > /dev/null ||
20450                 error "(6) Fail to list $DIR/$tdir/foo"
20451
20452         echo "Unlink hard links start at $(date)"
20453         unlinkmany $DIR/$tdir/foo/${PREFIX}_ 1000 ||
20454                 error "(7) Fail to unlink"
20455         echo "Unlink hard links finished at $(date)"
20456 }
20457 run_test 409 "Large amount of cross-MDTs hard links on the same file"
20458
20459 test_410()
20460 {
20461         [[ $CLIENT_VERSION -lt $(version_code 2.9.59) ]] &&
20462                 skip "Need client version at least 2.9.59"
20463
20464         # Create a file, and stat it from the kernel
20465         local testfile=$DIR/$tfile
20466         touch $testfile
20467
20468         local run_id=$RANDOM
20469         local my_ino=$(stat --format "%i" $testfile)
20470
20471         # Try to insert the module. This will always fail as the
20472         # module is designed to not be inserted.
20473         insmod $LUSTRE/tests/kernel/kinode.ko run_id=$run_id fname=$testfile \
20474             &> /dev/null
20475
20476         # Anything but success is a test failure
20477         dmesg | grep -q \
20478             "lustre_kinode_$run_id: inode numbers are identical: $my_ino" ||
20479             error "no inode match"
20480 }
20481 run_test 410 "Test inode number returned from kernel thread"
20482
20483 cleanup_test411_cgroup() {
20484         trap 0
20485         rmdir "$1"
20486 }
20487
20488 test_411() {
20489         local cg_basedir=/sys/fs/cgroup/memory
20490         # LU-9966
20491         test -f "$cg_basedir/memory.kmem.limit_in_bytes" ||
20492                 skip "no setup for cgroup"
20493
20494         dd if=/dev/zero of=$DIR/$tfile bs=1M count=100 conv=fsync ||
20495                 error "test file creation failed"
20496         cancel_lru_locks osc
20497
20498         # Create a very small memory cgroup to force a slab allocation error
20499         local cgdir=$cg_basedir/osc_slab_alloc
20500         mkdir $cgdir || error "cgroup mkdir '$cgdir' failed"
20501         trap "cleanup_test411_cgroup $cgdir" EXIT
20502         echo 2M > $cgdir/memory.kmem.limit_in_bytes
20503         echo 1M > $cgdir/memory.limit_in_bytes
20504
20505         # Should not LBUG, just be killed by oom-killer
20506         # dd will return 0 even allocation failure in some environment.
20507         # So don't check return value
20508         sh -c "echo \$$ > $cgdir/tasks && dd if=$DIR/$tfile of=/dev/null"
20509         cleanup_test411_cgroup $cgdir
20510
20511         return 0
20512 }
20513 run_test 411 "Slab allocation error with cgroup does not LBUG"
20514
20515 test_412() {
20516         [ $MDSCOUNT -lt 2 ] && skip_env "needs >= 2 MDTs"
20517         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20518                 skip "Need server version at least 2.10.55"
20519         fi
20520
20521         $LFS mkdir -i $((MDSCOUNT - 1)),$((MDSCOUNT - 2)) $DIR/$tdir ||
20522                 error "mkdir failed"
20523         $LFS getdirstripe $DIR/$tdir
20524         local stripe_index=$($LFS getdirstripe -i $DIR/$tdir)
20525         [ $stripe_index -eq $((MDSCOUNT - 1)) ] ||
20526                 error "expect $((MDSCOUT - 1)) get $stripe_index"
20527         local stripe_count=$($LFS getdirstripe -T $DIR/$tdir)
20528         [ $stripe_count -eq 2 ] ||
20529                 error "expect 2 get $stripe_count"
20530 }
20531 run_test 412 "mkdir on specific MDTs"
20532
20533 test_413a() {
20534         [ $MDSCOUNT -lt 2 ] &&
20535                 skip "We need at least 2 MDTs for this test"
20536
20537         if [ $(lustre_version_code mds1) -lt $(version_code 2.10.55) ]; then
20538                 skip "Need server version at least 2.10.55"
20539         fi
20540
20541         mkdir $DIR/$tdir || error "mkdir failed"
20542
20543         # find MDT that is the most full
20544         local max=$($LFS df | grep MDT |
20545                 awk 'BEGIN { a=0 }
20546                         { sub("%", "", $5)
20547                           if (0+$5 >= a)
20548                           {
20549                                 a = $5
20550                                 b = $6
20551                           }
20552                         }
20553                      END { split(b, c, ":")
20554                            sub("]", "", c[2])
20555                            print c[2]
20556                          }')
20557
20558         for i in $(seq $((MDSCOUNT - 1))); do
20559                 $LFS mkdir -c $i $DIR/$tdir/d$i ||
20560                         error "mkdir d$i failed"
20561                 $LFS getdirstripe $DIR/$tdir/d$i
20562                 local stripe_index=$($LFS getdirstripe -i $DIR/$tdir/d$i)
20563                 [ $stripe_index -ne $max ] ||
20564                         error "don't expect $max"
20565         done
20566 }
20567 run_test 413a "mkdir on less full MDTs"
20568
20569 test_413b() {
20570         [ $MDSCOUNT -lt 2 ] &&
20571                 skip "We need at least 2 MDTs for this test"
20572
20573         [ $MDS1_VERSION -lt $(version_code 2.12.52) ] &&
20574                 skip "Need server version at least 2.12.52"
20575
20576         mkdir $DIR/$tdir || error "mkdir failed"
20577         $LFS setdirstripe -D -i -1 -H space $DIR/$tdir ||
20578                 error "setdirstripe failed"
20579
20580         local qos_prio_free
20581         local qos_threshold_rr
20582         local count
20583
20584         qos_prio_free=$($LCTL get_param -n lmv.*.qos_prio_free | head -n1)
20585         qos_prio_free=${qos_prio_free%%%}
20586         qos_threshold_rr=$($LCTL get_param -n lmv.*.qos_threshold_rr | head -n1)
20587         qos_threshold_rr=${qos_threshold_rr%%%}
20588         qos_maxage=$($LCTL get_param -n lmv.*.qos_maxage)
20589
20590         stack_trap "$LCTL set_param lmv.*.qos_prio_free=$qos_prio_free" EXIT
20591         stack_trap "$LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr" \
20592                 EXIT
20593         stack_trap "$LCTL set_param lmv.*.qos_maxage=$qos_maxage" EXIT
20594
20595         echo "mkdir with roundrobin"
20596
20597         $LCTL set_param lmv.*.qos_threshold_rr=100
20598         for i in $(seq $((100 * MDSCOUNT))); do
20599                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20600         done
20601         for i in $(seq $MDSCOUNT); do
20602                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20603                         wc -w)
20604                 echo "$count directories created on MDT$((i - 1))"
20605                 [ $count -eq 100 ] || error "subdirs are not evenly distributed"
20606         done
20607
20608         rm -rf $DIR/$tdir/*
20609
20610         $LCTL set_param lmv.*.qos_threshold_rr=$qos_threshold_rr
20611         # Shorten statfs result age, so that it can be updated in time
20612         $LCTL set_param lmv.*.qos_maxage=1
20613         sleep_maxage
20614
20615         local ffree
20616         local max
20617         local min
20618         local max_index
20619         local min_index
20620
20621         ffree=($(lctl get_param -n mdc.*[mM][dD][cC]-[^M]*.filesfree | uniq))
20622         echo "MDT filesfree available: ${ffree[@]}"
20623         max=${ffree[0]}
20624         min=${ffree[0]}
20625         max_index=0
20626         min_index=0
20627         for ((i = 0; i < ${#ffree[@]}; i++)); do
20628                 if [[ ${ffree[i]} -gt $max ]]; then
20629                         max=${ffree[i]}
20630                         max_index=$i
20631                 fi
20632                 if [[ ${ffree[i]} -lt $min ]]; then
20633                         min=${ffree[i]}
20634                         min_index=$i
20635                 fi
20636         done
20637         echo "Min free files: MDT$min_index: $min"
20638         echo "Max free files: MDT$max_index: $max"
20639
20640         [ $min -eq 0 ] && skip "no free files in MDT$min_index"
20641         [ $min -gt 10000000 ] && skip "too much free files in MDT$min_index"
20642
20643         # Check if we need to generate uneven MDTs
20644         test_mkdir -i $min_index -c 1 -p $DIR/$tdir-MDT$min_index
20645         local threshold=10
20646         local diff=$((max - min))
20647         local diff2=$((diff * 100 / min))
20648
20649         echo -n "Check for uneven MDTs: "
20650         echo -n "diff=$diff files ($diff2%) must be > $threshold% ..."
20651
20652         if [ $diff2 -gt $threshold ]; then
20653                 echo "ok"
20654                 echo "Don't need to fill MDT$min_index"
20655         else
20656                 # generate uneven MDTs, create till 25% diff
20657                 echo "no"
20658                 diff2=$((threshold - diff2))
20659                 diff=$((min * diff2 / 100))
20660                 # 50 sec per 10000 files in vm
20661                 [ $diff -gt 40000 ] && [ "$SLOW" = "no" ] &&
20662                         skip "$diff files to create"
20663                 echo "Fill $diff2% diff in MDT$min_index with $diff files"
20664                 local i
20665                 local value="$(generate_string 1024)"
20666                 for i in $(seq $diff); do
20667                         $OPENFILE -f O_CREAT:O_LOV_DELAY_CREATE \
20668                                 $DIR/$tdir-MDT$min_index/f$i > /dev/null ||
20669                                 error "create f$i failed"
20670                         setfattr -n user.413b -v $value \
20671                                 $DIR/$tdir-MDT$min_index/f$i ||
20672                                 error "setfattr f$i failed"
20673                 done
20674         fi
20675
20676         min=$((100 *MDSCOUNT))
20677         max=0
20678
20679         echo "mkdir with balanced space usage"
20680         $LCTL set_param lmv.*.qos_prio_free=100
20681         for i in $(seq $((100 * MDSCOUNT))); do
20682                 mkdir $DIR/$tdir/subdir$i || error "mkdir subdir$i failed"
20683         done
20684         for i in $(seq $MDSCOUNT); do
20685                 count=$($LFS getdirstripe -i $DIR/$tdir/* | grep ^$((i - 1))$ |
20686                         wc -w)
20687                 echo "$count directories created on MDT$((i - 1))"
20688                 [ $min -gt $count ] && min=$count
20689                 [ $max -lt $count ] && max=$count
20690         done
20691         [ $((max - min)) -gt $MDSCOUNT ] ||
20692                 error "subdirs shouldn't be evenly distributed"
20693
20694         which getfattr > /dev/null 2>&1 || skip_env "no getfattr command"
20695
20696         $LFS setdirstripe -D -d $DIR/$tdir || error "setdirstripe -d failed"
20697         getfattr -n trusted.dmv $DIR/$tdir && error "default dir layout exists"
20698         true
20699 }
20700 run_test 413b "mkdir with balanced space usage"
20701
20702 test_414() {
20703 #define OBD_FAIL_PTLRPC_BULK_ATTACH      0x521
20704         $LCTL set_param fail_loc=0x80000521
20705         dd if=/dev/zero of=$DIR/$tfile bs=2M count=1 oflag=sync
20706         rm -f $DIR/$tfile
20707 }
20708 run_test 414 "simulate ENOMEM in ptlrpc_register_bulk()"
20709
20710 test_415() {
20711         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20712         [ $(lustre_version_code mds1) -lt $(version_code 2.11.52) ] &&
20713                 skip "Need server version at least 2.11.52"
20714
20715         # LU-11102
20716         local total
20717         local setattr_pid
20718         local start_time
20719         local end_time
20720         local duration
20721
20722         total=500
20723         # this test may be slow on ZFS
20724         [ "$mds1_FSTYPE" == "zfs" ] && total=100
20725
20726         # though this test is designed for striped directory, let's test normal
20727         # directory too since lock is always saved as CoS lock.
20728         test_mkdir $DIR/$tdir || error "mkdir $tdir"
20729         createmany -o $DIR/$tdir/$tfile. $total || error "createmany"
20730
20731         (
20732                 while true; do
20733                         touch $DIR/$tdir
20734                 done
20735         ) &
20736         setattr_pid=$!
20737
20738         start_time=$(date +%s)
20739         for i in $(seq $total); do
20740                 mrename $DIR/$tdir/$tfile.$i $DIR/$tdir/$tfile-new.$i \
20741                         > /dev/null
20742         done
20743         end_time=$(date +%s)
20744         duration=$((end_time - start_time))
20745
20746         kill -9 $setattr_pid
20747
20748         echo "rename $total files took $duration sec"
20749         [ $duration -lt 100 ] || error "rename took $duration sec"
20750 }
20751 run_test 415 "lock revoke is not missing"
20752
20753 test_416() {
20754         [ $(lustre_version_code mds1) -lt $(version_code 2.11.55) ] &&
20755                 skip "Need server version at least 2.11.55"
20756
20757         # define OBD_FAIL_OSD_TXN_START    0x19a
20758         do_facet mds1 lctl set_param fail_loc=0x19a
20759
20760         lfs mkdir -c $MDSCOUNT $DIR/$tdir
20761
20762         true
20763 }
20764 run_test 416 "transaction start failure won't cause system hung"
20765
20766 cleanup_417() {
20767         trap 0
20768         do_nodes $(comma_list $(mdts_nodes)) \
20769                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=1"
20770         do_nodes $(comma_list $(mdts_nodes)) \
20771                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=1"
20772         do_nodes $(comma_list $(mdts_nodes)) \
20773                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=1"
20774 }
20775
20776 test_417() {
20777         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
20778         [[ $MDS1_VERSION -lt $(version_code 2.11.56) ]] &&
20779                 skip "Need MDS version at least 2.11.56"
20780
20781         trap cleanup_417 RETURN EXIT
20782
20783         $LFS mkdir -i 1 $DIR/$tdir.1 || error "create remote dir $tdir.1 failed"
20784         do_nodes $(comma_list $(mdts_nodes)) \
20785                 "$LCTL set_param -n mdt.*MDT*.enable_dir_migration=0"
20786         $LFS migrate -m 0 $DIR/$tdir.1 &&
20787                 error "migrate dir $tdir.1 should fail"
20788
20789         do_nodes $(comma_list $(mdts_nodes)) \
20790                 "$LCTL set_param -n mdt.*MDT*.enable_remote_dir=0"
20791         $LFS mkdir -i 1 $DIR/$tdir.2 &&
20792                 error "create remote dir $tdir.2 should fail"
20793
20794         do_nodes $(comma_list $(mdts_nodes)) \
20795                 "$LCTL set_param -n mdt.*MDT*.enable_striped_dir=0"
20796         $LFS mkdir -c 2 $DIR/$tdir.3 &&
20797                 error "create striped dir $tdir.3 should fail"
20798         true
20799 }
20800 run_test 417 "disable remote dir, striped dir and dir migration"
20801
20802 # Checks that the outputs of df [-i] and lfs df [-i] match
20803 #
20804 # usage: check_lfs_df <blocks | inodes> <mountpoint>
20805 check_lfs_df() {
20806         local dir=$2
20807         local inodes
20808         local df_out
20809         local lfs_df_out
20810         local count
20811         local passed=false
20812
20813         # blocks or inodes
20814         [ "$1" == "blocks" ] && inodes= || inodes="-i"
20815
20816         for count in {1..100}; do
20817                 cancel_lru_locks
20818                 sync; sleep 0.2
20819
20820                 # read the lines of interest
20821                 df_out=($(df -P $inodes $dir | tail -n +2)) ||
20822                         error "df $inodes $dir | tail -n +2 failed"
20823                 lfs_df_out=($($LFS df $inodes $dir | grep summary:)) ||
20824                         error "lfs df $inodes $dir | grep summary: failed"
20825
20826                 # skip first substrings of each output as they are different
20827                 # "<NID>:/<fsname>" for df, "filesystem_summary:" for lfs df
20828                 # compare the two outputs
20829                 passed=true
20830                 for i in {1..5}; do
20831                         [ "${df_out[i]}" != "${lfs_df_out[i]}" ] && passed=false
20832                 done
20833                 $passed && break
20834         done
20835
20836         if ! $passed; then
20837                 df -P $inodes $dir
20838                 echo
20839                 lfs df $inodes $dir
20840                 error "df and lfs df $1 output mismatch: "      \
20841                       "df ${inodes}: ${df_out[*]}, "            \
20842                       "lfs df ${inodes}: ${lfs_df_out[*]}"
20843         fi
20844 }
20845
20846 test_418() {
20847         [ $PARALLEL == "yes" ] && skip "skip parallel run"
20848
20849         local dir=$DIR/$tdir
20850         local numfiles=$((RANDOM % 4096 + 2))
20851         local numblocks=$((RANDOM % 256 + 1))
20852
20853         wait_delete_completed
20854         test_mkdir $dir
20855
20856         # check block output
20857         check_lfs_df blocks $dir
20858         # check inode output
20859         check_lfs_df inodes $dir
20860
20861         # create a single file and retest
20862         echo "Creating a single file and testing"
20863         createmany -o $dir/$tfile- 1 &>/dev/null ||
20864                 error "creating 1 file in $dir failed"
20865         check_lfs_df blocks $dir
20866         check_lfs_df inodes $dir
20867
20868         # create a random number of files
20869         echo "Creating $((numfiles - 1)) files and testing"
20870         createmany -o $dir/$tfile- 1 $((numfiles - 1)) &>/dev/null ||
20871                 error "creating $((numfiles - 1)) files in $dir failed"
20872
20873         # write a random number of blocks to the first test file
20874         echo "Writing $numblocks 4K blocks and testing"
20875         dd if=/dev/urandom of=$dir/${tfile}-0 bs=4K conv=fsync \
20876                 count=$numblocks &>/dev/null ||
20877                 error "dd to $dir/${tfile}-0 failed"
20878
20879         # retest
20880         check_lfs_df blocks $dir
20881         check_lfs_df inodes $dir
20882
20883         unlinkmany $dir/$tfile- $numfiles &>/dev/null ||
20884                 error "unlinking $numfiles files in $dir failed"
20885 }
20886 run_test 418 "df and lfs df outputs match"
20887
20888 test_419()
20889 {
20890         local dir=$DIR/$tdir
20891
20892         mkdir -p $dir
20893         touch $dir/file
20894
20895         cancel_lru_locks mdc
20896
20897         #OBD_FAIL_LLITE_OPEN_BY_NAME    0x1410
20898         $LCTL set_param fail_loc=0x1410
20899         cat $dir/file
20900         $LCTL set_param fail_loc=0
20901         rm -rf $dir
20902 }
20903 run_test 419 "Verify open file by name doesn't crash kernel"
20904
20905 test_420()
20906 {
20907         [[ $MDS1_VERSION -ge $(version_code 2.12.53) ]] ||
20908                 skip "Need MDS version at least 2.12.53"
20909
20910         local SAVE_UMASK=$(umask)
20911         local dir=$DIR/$tdir
20912         local uname=$(getent passwd $RUNAS_ID | cut -d: -f1)
20913
20914         mkdir -p $dir
20915         umask 0000
20916         mkdir -m03777 $dir/testdir
20917         ls -dn $dir/testdir
20918         # Need to remove trailing '.' when SELinux is enabled
20919         local dirperms=$(ls -dn $dir/testdir |
20920                          awk '{ sub(/\.$/, "", $1); print $1}')
20921         [ $dirperms == "drwxrwsrwt" ] ||
20922                 error "incorrect perms on $dir/testdir"
20923
20924         su - $uname -c "PATH=$LUSTRE/tests:\$PATH; \
20925                 openfile -f O_RDONLY:O_CREAT -m 02755 $dir/testdir/testfile"
20926         ls -n $dir/testdir/testfile
20927         local fileperms=$(ls -n $dir/testdir/testfile |
20928                           awk '{ sub(/\.$/, "", $1); print $1}')
20929         [ $fileperms == "-rwxr-xr-x" ] ||
20930                 error "incorrect perms on $dir/testdir/testfile"
20931
20932         umask $SAVE_UMASK
20933 }
20934 run_test 420 "clear SGID bit on non-directories for non-members"
20935
20936 test_421a() {
20937         local cnt
20938         local fid1
20939         local fid2
20940
20941         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20942                 skip "Need MDS version at least 2.12.54"
20943
20944         test_mkdir $DIR/$tdir
20945         createmany -o $DIR/$tdir/f 3
20946         cnt=$(ls -1 $DIR/$tdir | wc -l)
20947         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20948
20949         fid1=$(lfs path2fid $DIR/$tdir/f1)
20950         fid2=$(lfs path2fid $DIR/$tdir/f2)
20951         $LFS rmfid $DIR $fid1 $fid2 || error "rmfid failed"
20952
20953         stat $DIR/$tdir/f1 && error "f1 still visible on the client"
20954         stat $DIR/$tdir/f2 && error "f2 still visible on the client"
20955
20956         cnt=$(ls -1 $DIR/$tdir | wc -l)
20957         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20958
20959         rm -f $DIR/$tdir/f3 || error "can't remove f3"
20960         createmany -o $DIR/$tdir/f 3
20961         cnt=$(ls -1 $DIR/$tdir | wc -l)
20962         [ $cnt != 3 ] && error "unexpected #files: $cnt"
20963
20964         fid1=$(lfs path2fid $DIR/$tdir/f1)
20965         fid2=$(lfs path2fid $DIR/$tdir/f2)
20966         echo "remove using fsname $FSNAME"
20967         $LFS rmfid $FSNAME $fid1 $fid2 || error "rmfid with fsname failed"
20968
20969         cnt=$(ls -1 $DIR/$tdir | wc -l)
20970         [ $cnt == 1 ] || error "unexpected #files after: $cnt"
20971 }
20972 run_test 421a "simple rm by fid"
20973
20974 test_421b() {
20975         local cnt
20976         local FID1
20977         local FID2
20978
20979         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
20980                 skip "Need MDS version at least 2.12.54"
20981
20982         test_mkdir $DIR/$tdir
20983         createmany -o $DIR/$tdir/f 3
20984         multiop_bg_pause $DIR/$tdir/f1 o_c || error "multiop failed to start"
20985         MULTIPID=$!
20986
20987         FID1=$(lfs path2fid $DIR/$tdir/f1)
20988         FID2=$(lfs path2fid $DIR/$tdir/f2)
20989         $LFS rmfid $DIR $FID1 $FID2 && error "rmfid didn't fail"
20990
20991         kill -USR1 $MULTIPID
20992         wait
20993
20994         cnt=$(ls $DIR/$tdir | wc -l)
20995         [ $cnt == 2 ] || error "unexpected #files after: $cnt"
20996 }
20997 run_test 421b "rm by fid on open file"
20998
20999 test_421c() {
21000         local cnt
21001         local FIDS
21002
21003         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21004                 skip "Need MDS version at least 2.12.54"
21005
21006         test_mkdir $DIR/$tdir
21007         createmany -o $DIR/$tdir/f 3
21008         touch $DIR/$tdir/$tfile
21009         createmany -l$DIR/$tdir/$tfile $DIR/$tdir/h 180
21010         cnt=$(ls -1 $DIR/$tdir | wc -l)
21011         [ $cnt != 184 ] && error "unexpected #files: $cnt"
21012
21013         FID1=$(lfs path2fid $DIR/$tdir/$tfile)
21014         $LFS rmfid $DIR $FID1 || error "rmfid failed"
21015
21016         cnt=$(ls $DIR/$tdir | wc -l)
21017         [ $cnt == 3 ] || error "unexpected #files after: $cnt"
21018 }
21019 run_test 421c "rm by fid against hardlinked files"
21020
21021 test_421d() {
21022         local cnt
21023         local FIDS
21024
21025         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21026                 skip "Need MDS version at least 2.12.54"
21027
21028         test_mkdir $DIR/$tdir
21029         createmany -o $DIR/$tdir/f 4097
21030         cnt=$(ls -1 $DIR/$tdir | wc -l)
21031         [ $cnt != 4097 ] && error "unexpected #files: $cnt"
21032
21033         FIDS=$(lfs path2fid $DIR/$tdir/f* | sed "s/[/][^:]*://g")
21034         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21035
21036         cnt=$(ls $DIR/$tdir | wc -l)
21037         rm -rf $DIR/$tdir
21038         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21039 }
21040 run_test 421d "rmfid en masse"
21041
21042 test_421e() {
21043         local cnt
21044         local FID
21045
21046         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21047         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21048                 skip "Need MDS version at least 2.12.54"
21049
21050         mkdir -p $DIR/$tdir
21051         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21052         createmany -o $DIR/$tdir/striped_dir/f 512
21053         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21054         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21055
21056         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21057                 sed "s/[/][^:]*://g")
21058         $LFS rmfid $DIR $FIDS || error "rmfid failed"
21059
21060         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21061         rm -rf $DIR/$tdir
21062         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21063 }
21064 run_test 421e "rmfid in DNE"
21065
21066 test_421f() {
21067         local cnt
21068         local FID
21069
21070         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21071                 skip "Need MDS version at least 2.12.54"
21072
21073         test_mkdir $DIR/$tdir
21074         touch $DIR/$tdir/f
21075         cnt=$(ls -1 $DIR/$tdir | wc -l)
21076         [ $cnt != 1 ] && error "unexpected #files: $cnt"
21077
21078         FID=$(lfs path2fid $DIR/$tdir/f)
21079         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (1)"
21080         # rmfid should fail
21081         cnt=$(ls -1 $DIR/$tdir | wc -l)
21082         [ $cnt != 1 ] && error "unexpected #files after (2): $cnt"
21083
21084         chmod a+rw $DIR/$tdir
21085         ls -la $DIR/$tdir
21086         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail (2)"
21087         # rmfid should fail
21088         cnt=$(ls -1 $DIR/$tdir | wc -l)
21089         [ $cnt != 1 ] && error "unexpected #files after (3): $cnt"
21090
21091         rm -f $DIR/$tdir/f
21092         $RUNAS touch $DIR/$tdir/f
21093         FID=$(lfs path2fid $DIR/$tdir/f)
21094         echo "rmfid as root"
21095         $LFS rmfid $DIR $FID || error "rmfid as root failed"
21096         cnt=$(ls -1 $DIR/$tdir | wc -l)
21097         [ $cnt == 0 ] || error "unexpected #files after (4): $cnt"
21098
21099         rm -f $DIR/$tdir/f
21100         $RUNAS touch $DIR/$tdir/f
21101         cnt=$(ls -1 $DIR/$tdir | wc -l)
21102         [ $cnt != 1 ] && error "unexpected #files (4): $cnt"
21103         FID=$(lfs path2fid $DIR/$tdir/f)
21104         # rmfid w/o user_fid2path mount option should fail
21105         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail(3)"
21106         cnt=$(ls -1 $DIR/$tdir | wc -l)
21107         [ $cnt == 1 ] || error "unexpected #files after (5): $cnt"
21108
21109         umount_client $MOUNT || error "failed to umount client"
21110         mount_client $MOUNT "$MOUNT_OPTS,user_fid2path" ||
21111                 error "failed to mount client'"
21112
21113         $RUNAS $LFS rmfid $DIR $FID || error "rmfid failed"
21114         # rmfid should succeed
21115         cnt=$(ls -1 $DIR/$tdir | wc -l)
21116         [ $cnt == 0 ] || error "unexpected #files after (6): $cnt"
21117
21118         # rmfid shouldn't allow to remove files due to dir's permission
21119         chmod a+rwx $DIR/$tdir
21120         touch $DIR/$tdir/f
21121         ls -la $DIR/$tdir
21122         FID=$(lfs path2fid $DIR/$tdir/f)
21123         $RUNAS $LFS rmfid $DIR $FID && error "rmfid didn't fail"
21124
21125         umount_client $MOUNT || error "failed to umount client"
21126         mount_client $MOUNT "$MOUNT_OPTS" ||
21127                 error "failed to mount client'"
21128
21129 }
21130 run_test 421f "rmfid checks permissions"
21131
21132 test_421g() {
21133         local cnt
21134         local FIDS
21135
21136         [ $MDSCOUNT -lt 2 ] && skip "needs >= 2 MDTs"
21137         [ $MDS1_VERSION -lt $(version_code 2.12.54) ] &&
21138                 skip "Need MDS version at least 2.12.54"
21139
21140         mkdir -p $DIR/$tdir
21141         $LFS setdirstripe -c$MDSCOUNT $DIR/$tdir/striped_dir
21142         createmany -o $DIR/$tdir/striped_dir/f 512
21143         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21144         [ $cnt != 512 ] && error "unexpected #files: $cnt"
21145
21146         FIDS=$(lfs path2fid $DIR/$tdir/striped_dir/f* |
21147                 sed "s/[/][^:]*://g")
21148
21149         rm -f $DIR/$tdir/striped_dir/f1*
21150         cnt=$(ls -1 $DIR/$tdir/striped_dir | wc -l)
21151         removed=$((512 - cnt))
21152
21153         # few files have been just removed, so we expect
21154         # rmfid to fail on their fids
21155         errors=$($LFS rmfid $DIR $FIDS 2>&1 | wc -l)
21156         [ $removed != $errors ] && error "$errors != $removed"
21157
21158         cnt=$(ls $DIR/$tdir/striped_dir | wc -l)
21159         rm -rf $DIR/$tdir
21160         [ $cnt == 0 ] || error "unexpected #files after: $cnt"
21161 }
21162 run_test 421g "rmfid to return errors properly"
21163
21164 prep_801() {
21165         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21166         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21167                 skip "Need server version at least 2.9.55"
21168
21169         start_full_debug_logging
21170 }
21171
21172 post_801() {
21173         stop_full_debug_logging
21174 }
21175
21176 barrier_stat() {
21177         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21178                 local st=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21179                            awk '/The barrier for/ { print $7 }')
21180                 echo $st
21181         else
21182                 local st=$(do_facet mgs $LCTL barrier_stat -s $FSNAME)
21183                 echo \'$st\'
21184         fi
21185 }
21186
21187 barrier_expired() {
21188         local expired
21189
21190         if [ $MGS_VERSION -le $(version_code 2.10.0) ]; then
21191                 expired=$(do_facet mgs $LCTL barrier_stat $FSNAME |
21192                           awk '/will be expired/ { print $7 }')
21193         else
21194                 expired=$(do_facet mgs $LCTL barrier_stat -t $FSNAME)
21195         fi
21196
21197         echo $expired
21198 }
21199
21200 test_801a() {
21201         prep_801
21202
21203         echo "Start barrier_freeze at: $(date)"
21204         #define OBD_FAIL_BARRIER_DELAY          0x2202
21205         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21206         # Do not reduce barrier time - See LU-11873
21207         do_facet mgs $LCTL barrier_freeze $FSNAME 20 &
21208
21209         sleep 2
21210         local b_status=$(barrier_stat)
21211         echo "Got barrier status at: $(date)"
21212         [ "$b_status" = "'freezing_p1'" ] ||
21213                 error "(1) unexpected barrier status $b_status"
21214
21215         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21216         wait
21217         b_status=$(barrier_stat)
21218         [ "$b_status" = "'frozen'" ] ||
21219                 error "(2) unexpected barrier status $b_status"
21220
21221         local expired=$(barrier_expired)
21222         echo "sleep $((expired + 3)) seconds, then the barrier will be expired"
21223         sleep $((expired + 3))
21224
21225         b_status=$(barrier_stat)
21226         [ "$b_status" = "'expired'" ] ||
21227                 error "(3) unexpected barrier status $b_status"
21228
21229         # Do not reduce barrier time - See LU-11873
21230         do_facet mgs $LCTL barrier_freeze $FSNAME 20 ||
21231                 error "(4) fail to freeze barrier"
21232
21233         b_status=$(barrier_stat)
21234         [ "$b_status" = "'frozen'" ] ||
21235                 error "(5) unexpected barrier status $b_status"
21236
21237         echo "Start barrier_thaw at: $(date)"
21238         #define OBD_FAIL_BARRIER_DELAY          0x2202
21239         do_facet mgs $LCTL set_param fail_val=5 fail_loc=0x2202
21240         do_facet mgs $LCTL barrier_thaw $FSNAME &
21241
21242         sleep 2
21243         b_status=$(barrier_stat)
21244         echo "Got barrier status at: $(date)"
21245         [ "$b_status" = "'thawing'" ] ||
21246                 error "(6) unexpected barrier status $b_status"
21247
21248         do_facet mgs $LCTL set_param fail_val=0 fail_loc=0
21249         wait
21250         b_status=$(barrier_stat)
21251         [ "$b_status" = "'thawed'" ] ||
21252                 error "(7) unexpected barrier status $b_status"
21253
21254         #define OBD_FAIL_BARRIER_FAILURE        0x2203
21255         do_facet $SINGLEMDS $LCTL set_param fail_loc=0x2203
21256         do_facet mgs $LCTL barrier_freeze $FSNAME
21257
21258         b_status=$(barrier_stat)
21259         [ "$b_status" = "'failed'" ] ||
21260                 error "(8) unexpected barrier status $b_status"
21261
21262         do_facet $SINGLEMDS $LCTL set_param fail_loc=0
21263         do_facet mgs $LCTL barrier_thaw $FSNAME
21264
21265         post_801
21266 }
21267 run_test 801a "write barrier user interfaces and stat machine"
21268
21269 test_801b() {
21270         prep_801
21271
21272         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21273         createmany -d $DIR/$tdir/d 6 || "(2) fail to mkdir"
21274         touch $DIR/$tdir/d2/f10 || error "(3) fail to touch"
21275         touch $DIR/$tdir/d3/f11 || error "(4) fail to touch"
21276         touch $DIR/$tdir/d4/f12 || error "(5) fail to touch"
21277
21278         cancel_lru_locks mdc
21279
21280         # 180 seconds should be long enough
21281         do_facet mgs $LCTL barrier_freeze $FSNAME 180
21282
21283         local b_status=$(barrier_stat)
21284         [ "$b_status" = "'frozen'" ] ||
21285                 error "(6) unexpected barrier status $b_status"
21286
21287         mkdir $DIR/$tdir/d0/d10 &
21288         mkdir_pid=$!
21289
21290         touch $DIR/$tdir/d1/f13 &
21291         touch_pid=$!
21292
21293         ln $DIR/$tdir/d2/f10 $DIR/$tdir/d2/f14 &
21294         ln_pid=$!
21295
21296         mv $DIR/$tdir/d3/f11 $DIR/$tdir/d3/f15 &
21297         mv_pid=$!
21298
21299         rm -f $DIR/$tdir/d4/f12 &
21300         rm_pid=$!
21301
21302         stat $DIR/$tdir/d5 || error "(7) stat should succeed"
21303
21304         # To guarantee taht the 'stat' is not blocked
21305         b_status=$(barrier_stat)
21306         [ "$b_status" = "'frozen'" ] ||
21307                 error "(8) unexpected barrier status $b_status"
21308
21309         # let above commands to run at background
21310         sleep 5
21311
21312         ps -p $mkdir_pid || error "(9) mkdir should be blocked"
21313         ps -p $touch_pid || error "(10) touch should be blocked"
21314         ps -p $ln_pid || error "(11) link should be blocked"
21315         ps -p $mv_pid || error "(12) rename should be blocked"
21316         ps -p $rm_pid || error "(13) unlink should be blocked"
21317
21318         b_status=$(barrier_stat)
21319         [ "$b_status" = "'frozen'" ] ||
21320                 error "(14) unexpected barrier status $b_status"
21321
21322         do_facet mgs $LCTL barrier_thaw $FSNAME
21323         b_status=$(barrier_stat)
21324         [ "$b_status" = "'thawed'" ] ||
21325                 error "(15) unexpected barrier status $b_status"
21326
21327         wait $mkdir_pid || error "(16) mkdir should succeed"
21328         wait $touch_pid || error "(17) touch should succeed"
21329         wait $ln_pid || error "(18) link should succeed"
21330         wait $mv_pid || error "(19) rename should succeed"
21331         wait $rm_pid || error "(20) unlink should succeed"
21332
21333         post_801
21334 }
21335 run_test 801b "modification will be blocked by write barrier"
21336
21337 test_801c() {
21338         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21339
21340         prep_801
21341
21342         stop mds2 || error "(1) Fail to stop mds2"
21343
21344         do_facet mgs $LCTL barrier_freeze $FSNAME 30
21345
21346         local b_status=$(barrier_stat)
21347         [ "$b_status" = "'expired'" ] || [ "$b_status" = "'failed'" ] || {
21348                 do_facet mgs $LCTL barrier_thaw $FSNAME
21349                 error "(2) unexpected barrier status $b_status"
21350         }
21351
21352         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21353                 error "(3) Fail to rescan barrier bitmap"
21354
21355         # Do not reduce barrier time - See LU-11873
21356         do_facet mgs $LCTL barrier_freeze $FSNAME 20
21357
21358         b_status=$(barrier_stat)
21359         [ "$b_status" = "'frozen'" ] ||
21360                 error "(4) unexpected barrier status $b_status"
21361
21362         do_facet mgs $LCTL barrier_thaw $FSNAME
21363         b_status=$(barrier_stat)
21364         [ "$b_status" = "'thawed'" ] ||
21365                 error "(5) unexpected barrier status $b_status"
21366
21367         local devname=$(mdsdevname 2)
21368
21369         start mds2 $devname $MDS_MOUNT_OPTS || error "(6) Fail to start mds2"
21370
21371         do_facet mgs $LCTL barrier_rescan $FSNAME ||
21372                 error "(7) Fail to rescan barrier bitmap"
21373
21374         post_801
21375 }
21376 run_test 801c "rescan barrier bitmap"
21377
21378 saved_MGS_MOUNT_OPTS=$MGS_MOUNT_OPTS
21379 saved_MDS_MOUNT_OPTS=$MDS_MOUNT_OPTS
21380 saved_OST_MOUNT_OPTS=$OST_MOUNT_OPTS
21381 saved_MOUNT_OPTS=$MOUNT_OPTS
21382
21383 cleanup_802a() {
21384         trap 0
21385
21386         stopall
21387         MGS_MOUNT_OPTS=$saved_MGS_MOUNT_OPTS
21388         MDS_MOUNT_OPTS=$saved_MDS_MOUNT_OPTS
21389         OST_MOUNT_OPTS=$saved_OST_MOUNT_OPTS
21390         MOUNT_OPTS=$saved_MOUNT_OPTS
21391         setupall
21392 }
21393
21394 test_802a() {
21395         [[ $mds1_FSTYPE = zfs ]] || skip "ZFS specific test"
21396         [[ $(lustre_version_code mds1) -lt $(version_code 2.9.55) ]] ||
21397         [[ $OST1_VERSION -lt $(version_code 2.9.55) ]] &&
21398                 skip "Need server version at least 2.9.55"
21399
21400         [[ $ENABLE_QUOTA ]] && skip "Quota enabled for read-only test"
21401
21402         mkdir $DIR/$tdir || error "(1) fail to mkdir"
21403
21404         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21405                 error "(2) Fail to copy"
21406
21407         trap cleanup_802a EXIT
21408
21409         # sync by force before remount as readonly
21410         sync; sync_all_data; sleep 3; sync_all_data
21411
21412         stopall
21413
21414         MGS_MOUNT_OPTS=$(csa_add "$MGS_MOUNT_OPTS" -o rdonly_dev)
21415         MDS_MOUNT_OPTS=$(csa_add "$MDS_MOUNT_OPTS" -o rdonly_dev)
21416         OST_MOUNT_OPTS=$(csa_add "$OST_MOUNT_OPTS" -o rdonly_dev)
21417
21418         echo "Mount the server as read only"
21419         setupall server_only || error "(3) Fail to start servers"
21420
21421         echo "Mount client without ro should fail"
21422         mount_client $MOUNT &&
21423                 error "(4) Mount client without 'ro' should fail"
21424
21425         echo "Mount client with ro should succeed"
21426         MOUNT_OPTS=$(csa_add "$MOUNT_OPTS" -o ro)
21427         mount_client $MOUNT ||
21428                 error "(5) Mount client with 'ro' should succeed"
21429
21430         echo "Modify should be refused"
21431         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21432
21433         echo "Read should be allowed"
21434         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21435                 error "(7) Read should succeed under ro mode"
21436
21437         cleanup_802a
21438 }
21439 run_test 802a "simulate readonly device"
21440
21441 test_802b() {
21442         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21443         remote_mds_nodsh && skip "remote MDS with nodsh"
21444
21445         do_facet $SINGLEMDS $LCTL get_param mdt.*.readonly ||
21446                 skip "readonly option not available"
21447
21448         $LFS mkdir -i 0 -c 1 $DIR/$tdir || error "(1) fail to mkdir"
21449
21450         cp $LUSTRE/tests/test-framework.sh $DIR/$tdir/ ||
21451                 error "(2) Fail to copy"
21452
21453         # write back all cached data before setting MDT to readonly
21454         cancel_lru_locks
21455         sync_all_data
21456
21457         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=1
21458         stack_trap "do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0" EXIT
21459
21460         echo "Modify should be refused"
21461         touch $DIR/$tdir/guard && error "(6) Touch should fail under ro mode"
21462
21463         echo "Read should be allowed"
21464         diff $LUSTRE/tests/test-framework.sh $DIR/$tdir/test-framework.sh ||
21465                 error "(7) Read should succeed under ro mode"
21466
21467         # disable readonly
21468         do_facet $SINGLEMDS $LCTL set_param mdt.*.readonly=0
21469 }
21470 run_test 802b "be able to set MDTs to readonly"
21471
21472 test_803() {
21473         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21474         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21475                 skip "MDS needs to be newer than 2.10.54"
21476
21477         mkdir -p $DIR/$tdir
21478         # Create some objects on all MDTs to trigger related logs objects
21479         for idx in $(seq $MDSCOUNT); do
21480                 $LFS mkdir -c $MDSCOUNT -i $((idx % $MDSCOUNT)) \
21481                         $DIR/$tdir/dir${idx} ||
21482                         error "Fail to create $DIR/$tdir/dir${idx}"
21483         done
21484
21485         sync; sleep 3
21486         wait_delete_completed # ensure old test cleanups are finished
21487         echo "before create:"
21488         $LFS df -i $MOUNT
21489         local before_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21490
21491         for i in {1..10}; do
21492                 $LFS mkdir -c 1 -i 1 $DIR/$tdir/foo$i ||
21493                         error "Fail to create $DIR/$tdir/foo$i"
21494         done
21495
21496         sync; sleep 3
21497         echo "after create:"
21498         $LFS df -i $MOUNT
21499         local after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21500
21501         # allow for an llog to be cleaned up during the test
21502         [ $after_used -ge $((before_used + 10 - 1)) ] ||
21503                 error "before ($before_used) + 10 > after ($after_used)"
21504
21505         for i in {1..10}; do
21506                 rm -rf $DIR/$tdir/foo$i ||
21507                         error "Fail to remove $DIR/$tdir/foo$i"
21508         done
21509
21510         sleep 3 # avoid MDT return cached statfs
21511         wait_delete_completed
21512         echo "after unlink:"
21513         $LFS df -i $MOUNT
21514         after_used=$($LFS df -i | grep MDT0000_UUID | awk '{print $3}')
21515
21516         # allow for an llog to be created during the test
21517         [ $after_used -le $((before_used + 1)) ] ||
21518                 error "after ($after_used) > before ($before_used) + 1"
21519 }
21520 run_test 803 "verify agent object for remote object"
21521
21522 test_804() {
21523         [[ $MDSCOUNT -lt 2 ]] && skip_env "needs >= 2 MDTs"
21524         [ $MDS1_VERSION -lt $(version_code 2.10.54) ] &&
21525                 skip "MDS needs to be newer than 2.10.54"
21526         [ "$mds1_FSTYPE" != "ldiskfs" ] && skip_env "ldiskfs only test"
21527
21528         mkdir -p $DIR/$tdir
21529         $LFS mkdir -c 1 -i 1 $DIR/$tdir/dir0 ||
21530                 error "Fail to create $DIR/$tdir/dir0"
21531
21532         local fid=$($LFS path2fid $DIR/$tdir/dir0)
21533         local dev=$(mdsdevname 2)
21534
21535         do_facet mds2 "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21536                 grep ${fid} || error "NOT found agent entry for dir0"
21537
21538         $LFS mkdir -c $MDSCOUNT -i 0 $DIR/$tdir/dir1 ||
21539                 error "Fail to create $DIR/$tdir/dir1"
21540
21541         touch $DIR/$tdir/dir1/foo0 ||
21542                 error "Fail to create $DIR/$tdir/dir1/foo0"
21543         fid=$($LFS path2fid $DIR/$tdir/dir1/foo0)
21544         local rc=0
21545
21546         for idx in $(seq $MDSCOUNT); do
21547                 dev=$(mdsdevname $idx)
21548                 do_facet mds${idx} \
21549                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21550                         grep ${fid} && rc=$idx
21551         done
21552
21553         mv $DIR/$tdir/dir1/foo0 $DIR/$tdir/dir1/foo1 ||
21554                 error "Fail to rename foo0 to foo1"
21555         if [ $rc -eq 0 ]; then
21556                 for idx in $(seq $MDSCOUNT); do
21557                         dev=$(mdsdevname $idx)
21558                         do_facet mds${idx} \
21559                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21560                         grep ${fid} && rc=$idx
21561                 done
21562         fi
21563
21564         mv $DIR/$tdir/dir1/foo1 $DIR/$tdir/dir1/foo2 ||
21565                 error "Fail to rename foo1 to foo2"
21566         if [ $rc -eq 0 ]; then
21567                 for idx in $(seq $MDSCOUNT); do
21568                         dev=$(mdsdevname $idx)
21569                         do_facet mds${idx} \
21570                         "$DEBUGFS -c -R 'ls /REMOTE_PARENT_DIR' $dev" |
21571                         grep ${fid} && rc=$idx
21572                 done
21573         fi
21574
21575         [ $rc -ne 0 ] || error "NOT found agent entry for foo"
21576
21577         ln $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir0/guard ||
21578                 error "Fail to link to $DIR/$tdir/dir1/foo2"
21579         mv $DIR/$tdir/dir1/foo2 $DIR/$tdir/dir1/foo0 ||
21580                 error "Fail to rename foo2 to foo0"
21581         unlink $DIR/$tdir/dir1/foo0 ||
21582                 error "Fail to unlink $DIR/$tdir/dir1/foo0"
21583         rm -rf $DIR/$tdir/dir0 ||
21584                 error "Fail to rm $DIR/$tdir/dir0"
21585
21586         for idx in $(seq $MDSCOUNT); do
21587                 dev=$(mdsdevname $idx)
21588                 rc=0
21589
21590                 stop mds${idx}
21591                 run_e2fsck $(facet_active_host mds$idx) $dev -n ||
21592                         rc=$?
21593                 start mds${idx} $dev $MDS_MOUNT_OPTS ||
21594                         error "mount mds$idx failed"
21595                 df $MOUNT > /dev/null 2>&1
21596
21597                 # e2fsck should not return error
21598                 [ $rc -eq 0 ] ||
21599                         error "e2fsck detected error on MDT${idx}: rc=$rc"
21600         done
21601 }
21602 run_test 804 "verify agent entry for remote entry"
21603
21604 cleanup_805() {
21605         do_facet $SINGLEMDS zfs set quota=$old $fsset
21606         unlinkmany $DIR/$tdir/f- 1000000
21607         trap 0
21608 }
21609
21610 test_805() {
21611         local zfs_version=$(do_node $SINGLEMDS cat /sys/module/zfs/version)
21612         [ "$mds1_FSTYPE" != "zfs" ] && skip "ZFS specific test"
21613         [ $(version_code $zfs_version) -lt $(version_code 0.7.2) ] &&
21614                 skip "netfree not implemented before 0.7"
21615         [[ $MDS1_VERSION -ge $(version_code 2.10.57) ]] ||
21616                 skip "Need MDS version at least 2.10.57"
21617
21618         local fsset
21619         local freekb
21620         local usedkb
21621         local old
21622         local quota
21623         local pref="osd-zfs.lustre-MDT0000."
21624
21625         # limit available space on MDS dataset to meet nospace issue
21626         # quickly. then ZFS 0.7.2 can use reserved space if asked
21627         # properly (using netfree flag in osd_declare_destroy()
21628         fsset=$(do_facet $SINGLEMDS lctl get_param -n $pref.mntdev)
21629         old=$(do_facet $SINGLEMDS zfs get -H quota $fsset | \
21630                 gawk '{print $3}')
21631         freekb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytesfree)
21632         usedkb=$(do_facet $SINGLEMDS lctl get_param -n $pref.kbytestotal)
21633         let "usedkb=usedkb-freekb"
21634         let "freekb=freekb/2"
21635         if let "freekb > 5000"; then
21636                 let "freekb=5000"
21637         fi
21638         do_facet $SINGLEMDS zfs set quota=$(((usedkb+freekb)*1024)) $fsset
21639         trap cleanup_805 EXIT
21640         mkdir $DIR/$tdir
21641         $LFS setstripe -E 1M -L mdt $DIR/$tdir || error "DoM not working"
21642         createmany -m $DIR/$tdir/f- 1000000 && error "ENOSPC wasn't met"
21643         rm -rf $DIR/$tdir || error "not able to remove"
21644         do_facet $SINGLEMDS zfs set quota=$old $fsset
21645         trap 0
21646 }
21647 run_test 805 "ZFS can remove from full fs"
21648
21649 # Size-on-MDS test
21650 check_lsom_data()
21651 {
21652         local file=$1
21653         local size=$($LFS getsom -s $file)
21654         local expect=$(stat -c %s $file)
21655
21656         [[ $size == $expect ]] ||
21657                 error "$file expected size: $expect, got: $size"
21658
21659         local blocks=$($LFS getsom -b $file)
21660         expect=$(stat -c %b $file)
21661         [[ $blocks == $expect ]] ||
21662                 error "$file expected blocks: $expect, got: $blocks"
21663 }
21664
21665 check_lsom_size()
21666 {
21667         local size=$($LFS getsom -s $1)
21668         local expect=$2
21669
21670         [[ $size == $expect ]] ||
21671                 error "$file expected size: $expect, got: $size"
21672 }
21673
21674 test_806() {
21675         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21676                 skip "Need MDS version at least 2.11.52"
21677
21678         local bs=1048576
21679
21680         touch $DIR/$tfile || error "touch $tfile failed"
21681
21682         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21683         save_lustre_params client "llite.*.xattr_cache" > $save
21684         lctl set_param llite.*.xattr_cache=0
21685         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21686
21687         # single-threaded write
21688         echo "Test SOM for single-threaded write"
21689         dd if=/dev/zero of=$DIR/$tfile bs=$bs count=1 ||
21690                 error "write $tfile failed"
21691         check_lsom_size $DIR/$tfile $bs
21692
21693         local num=32
21694         local size=$(($num * $bs))
21695         local offset=0
21696         local i
21697
21698         echo "Test SOM for single client multi-threaded($num) write"
21699         $TRUNCATE $DIR/$tfile 0
21700         for ((i = 0; i < $num; i++)); do
21701                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21702                 local pids[$i]=$!
21703                 offset=$((offset + $bs))
21704         done
21705         for (( i=0; i < $num; i++ )); do
21706                 wait ${pids[$i]}
21707         done
21708         check_lsom_size $DIR/$tfile $size
21709
21710         $TRUNCATE $DIR/$tfile 0
21711         for ((i = 0; i < $num; i++)); do
21712                 offset=$((offset - $bs))
21713                 $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21714                 local pids[$i]=$!
21715         done
21716         for (( i=0; i < $num; i++ )); do
21717                 wait ${pids[$i]}
21718         done
21719         check_lsom_size $DIR/$tfile $size
21720
21721         # multi-client wirtes
21722         num=$(get_node_count ${CLIENTS//,/ })
21723         size=$(($num * $bs))
21724         offset=0
21725         i=0
21726
21727         echo "Test SOM for multi-client ($num) writes"
21728         $TRUNCATE $DIR/$tfile 0
21729         for client in ${CLIENTS//,/ }; do
21730                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21731                 local pids[$i]=$!
21732                 i=$((i + 1))
21733                 offset=$((offset + $bs))
21734         done
21735         for (( i=0; i < $num; i++ )); do
21736                 wait ${pids[$i]}
21737         done
21738         check_lsom_size $DIR/$tfile $offset
21739
21740         i=0
21741         $TRUNCATE $DIR/$tfile 0
21742         for client in ${CLIENTS//,/ }; do
21743                 offset=$((offset - $bs))
21744                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21745                 local pids[$i]=$!
21746                 i=$((i + 1))
21747         done
21748         for (( i=0; i < $num; i++ )); do
21749                 wait ${pids[$i]}
21750         done
21751         check_lsom_size $DIR/$tfile $size
21752
21753         # verify truncate
21754         echo "Test SOM for truncate"
21755         $TRUNCATE $DIR/$tfile 1048576
21756         check_lsom_size $DIR/$tfile 1048576
21757         $TRUNCATE $DIR/$tfile 1234
21758         check_lsom_size $DIR/$tfile 1234
21759
21760         # verify SOM blocks count
21761         echo "Verify SOM block count"
21762         $TRUNCATE $DIR/$tfile 0
21763         $MULTIOP $DIR/$tfile oO_TRUNC:O_RDWR:w1048576YSc ||
21764                 error "failed to write file $tfile"
21765         check_lsom_data $DIR/$tfile
21766 }
21767 run_test 806 "Verify Lazy Size on MDS"
21768
21769 test_807() {
21770         [ -n "$FILESET" ] && skip "Not functional for FILESET set"
21771         [ $MDS1_VERSION -lt $(version_code 2.11.52) ] &&
21772                 skip "Need MDS version at least 2.11.52"
21773
21774         # Registration step
21775         changelog_register || error "changelog_register failed"
21776         local cl_user="${CL_USERS[$SINGLEMDS]%% *}"
21777         changelog_users $SINGLEMDS | grep -q $cl_user ||
21778                 error "User $cl_user not found in changelog_users"
21779
21780         local save="$TMP/$TESTSUITE-$TESTNAME.parameters"
21781         save_lustre_params client "llite.*.xattr_cache" > $save
21782         lctl set_param llite.*.xattr_cache=0
21783         stack_trap "restore_lustre_params < $save; rm -f $save" EXIT
21784
21785         rm -rf $DIR/$tdir || error "rm $tdir failed"
21786         mkdir -p $DIR/$tdir || error "mkdir $tdir failed"
21787         touch $DIR/$tdir/trunc || error "touch $tdir/trunc failed"
21788         $TRUNCATE $DIR/$tdir/trunc 1024 || error "truncate $tdir/trunc failed"
21789         $TRUNCATE $DIR/$tdir/trunc 1048576 ||
21790                 error "truncate $tdir/trunc failed"
21791
21792         local bs=1048576
21793         dd if=/dev/zero of=$DIR/$tdir/single_dd bs=$bs count=1 ||
21794                 error "write $tfile failed"
21795
21796         # multi-client wirtes
21797         local num=$(get_node_count ${CLIENTS//,/ })
21798         local offset=0
21799         local i=0
21800
21801         echo "Test SOM for multi-client ($num) writes"
21802         touch $DIR/$tfile || error "touch $tfile failed"
21803         $TRUNCATE $DIR/$tfile 0
21804         for client in ${CLIENTS//,/ }; do
21805                 do_node $client $MULTIOP $DIR/$tfile Oz${offset}w${bs}c &
21806                 local pids[$i]=$!
21807                 i=$((i + 1))
21808                 offset=$((offset + $bs))
21809         done
21810         for (( i=0; i < $num; i++ )); do
21811                 wait ${pids[$i]}
21812         done
21813
21814         sleep 5
21815         $LSOM_SYNC -u $cl_user -m $FSNAME-MDT0000 $MOUNT
21816         check_lsom_data $DIR/$tdir/trunc
21817         check_lsom_data $DIR/$tdir/single_dd
21818         check_lsom_data $DIR/$tfile
21819
21820         rm -rf $DIR/$tdir
21821         # Deregistration step
21822         changelog_deregister || error "changelog_deregister failed"
21823 }
21824 run_test 807 "verify LSOM syncing tool"
21825
21826 check_som_nologged()
21827 {
21828         local lines=$($LFS changelog $FSNAME-MDT0000 |
21829                 grep 'x=trusted.som' | wc -l)
21830         [ $lines -ne 0 ] && error "trusted.som xattr is logged in Changelogs"
21831 }
21832
21833 test_808() {
21834         [ $MDS1_VERSION -lt $(version_code 2.11.55) ] &&
21835                 skip "Need MDS version at least 2.11.55"
21836
21837         # Registration step
21838         changelog_register || error "changelog_register failed"
21839
21840         touch $DIR/$tfile || error "touch $tfile failed"
21841         check_som_nologged
21842
21843         dd if=/dev/zero of=$DIR/$tfile bs=1048576 count=1 ||
21844                 error "write $tfile failed"
21845         check_som_nologged
21846
21847         $TRUNCATE $DIR/$tfile 1234
21848         check_som_nologged
21849
21850         $TRUNCATE $DIR/$tfile 1048576
21851         check_som_nologged
21852
21853         # Deregistration step
21854         changelog_deregister || error "changelog_deregister failed"
21855 }
21856 run_test 808 "Check trusted.som xattr not logged in Changelogs"
21857
21858 check_som_nodata()
21859 {
21860         $LFS getsom $1
21861         [[ $? -eq 61 ]] || error "DoM-only file $1 has SOM xattr"
21862 }
21863
21864 test_809() {
21865         [ $MDS1_VERSION -lt $(version_code 2.11.56) ] &&
21866                 skip "Need MDS version at least 2.11.56"
21867
21868         $LFS setstripe -E 1M -L mdt $DIR/$tfile ||
21869                 error "failed to create DoM-only file $DIR/$tfile"
21870         touch $DIR/$tfile || error "touch $tfile failed"
21871         check_som_nodata $DIR/$tfile
21872
21873         dd if=/dev/zero of=$DIR/$tfile bs=2048 count=1 ||
21874                 error "write $tfile failed"
21875         check_som_nodata $DIR/$tfile
21876
21877         $TRUNCATE $DIR/$tfile 1234
21878         check_som_nodata $DIR/$tfile
21879
21880         $TRUNCATE $DIR/$tfile 4097
21881         check_som_nodata $DIR/$file
21882 }
21883 run_test 809 "Verify no SOM xattr store for DoM-only files"
21884
21885 test_810() {
21886         [ $PARALLEL == "yes" ] && skip "skip parallel run"
21887         $GSS && skip_env "could not run with gss"
21888
21889         set_checksums 1
21890         stack_trap "set_checksums $ORIG_CSUM" EXIT
21891         stack_trap "set_checksum_type $ORIG_CSUM_TYPE" EXIT
21892
21893         local csum
21894         local before
21895         local after
21896         for csum in $CKSUM_TYPES; do
21897                 #define OBD_FAIL_OSC_NO_GRANT   0x411
21898                 $LCTL set_param osc.*.checksum_type=$csum fail_loc=0x411
21899                 for i in "10240 0" "10000 0" "4000 1" "500 1"; do
21900                         eval set -- $i
21901                         dd if=/dev/urandom of=$DIR/$tfile bs=$1 count=2 seek=$2
21902                         before=$(md5sum $DIR/$tfile)
21903                         $LCTL set_param ldlm.namespaces.*osc*.lru_size=clear
21904                         after=$(md5sum $DIR/$tfile)
21905                         [ "$before" == "$after" ] ||
21906                                 error "$csum: $before != $after bs=$1 seek=$2"
21907                 done
21908         done
21909 }
21910 run_test 810 "partial page writes on ZFS (LU-11663)"
21911
21912 test_811() {
21913         [ $(lustre_version_code $SINGLEMDS) -lt $(version_code 2.11.56) ] &&
21914                 skip "Need MDS version at least 2.11.56"
21915
21916         #define OBD_FAIL_MDS_ORPHAN_DELETE      0x165
21917         do_facet mds1 $LCTL set_param fail_loc=0x165
21918         $MULTIOP $DIR/$tfile Ouc || error "multiop failed"
21919
21920         stop mds1
21921         start mds1 $(mdsdevname 1) $MDS_MOUNT_OPTS
21922
21923         sleep 5
21924         [[ $(do_facet mds1 pgrep orph_.*-MDD | wc -l) -eq 0 ]] ||
21925                 error "MDD orphan cleanup thread not quit"
21926 }
21927 run_test 811 "orphan name stub can be cleaned up in startup"
21928
21929 test_812() {
21930         [ $OST1_VERSION -lt $(version_code 2.12.51) ] &&
21931                 skip "OST < 2.12.51 doesn't support this fail_loc"
21932         [ "$SHARED_KEY" = true ] &&
21933                 skip "OSC connections never go IDLE with Shared-Keys enabled"
21934
21935         $LFS setstripe -c 1 -i 0 $DIR/$tfile
21936         # ensure ost1 is connected
21937         stat $DIR/$tfile >/dev/null || error "can't stat"
21938         wait_osc_import_state client ost1 FULL
21939         # no locks, no reqs to let the connection idle
21940         cancel_lru_locks osc
21941
21942         # delay OST_DISCONNECT on OST1 to put OSC into intermediate state
21943 #define OBD_FAIL_OST_DISCONNECT_DELAY    0x245
21944         do_facet ost1 "$LCTL set_param fail_loc=0x245 fail_val=8"
21945         wait_osc_import_state client ost1 CONNECTING
21946         do_facet ost1 "$LCTL set_param fail_loc=0 fail_val=0"
21947
21948         stat $DIR/$tfile >/dev/null || error "can't stat file"
21949 }
21950 run_test 812 "do not drop reqs generated when imp is going to idle (LU-11951)"
21951
21952 test_813() {
21953         local file_heat_sav=$($LCTL get_param -n llite.*.file_heat 2>/dev/null)
21954         [ -z "$file_heat_sav" ] && skip "no file heat support"
21955
21956         local readsample
21957         local writesample
21958         local readbyte
21959         local writebyte
21960         local readsample1
21961         local writesample1
21962         local readbyte1
21963         local writebyte1
21964
21965         local period_second=$($LCTL get_param -n llite.*.heat_period_second)
21966         local decay_pct=$($LCTL get_param -n llite.*.heat_decay_percentage)
21967
21968         $LCTL set_param -n llite.*.file_heat=1
21969         echo "Turn on file heat"
21970         echo "Period second: $period_second, Decay percentage: $decay_pct"
21971
21972         echo "QQQQ" > $DIR/$tfile
21973         echo "QQQQ" > $DIR/$tfile
21974         echo "QQQQ" > $DIR/$tfile
21975         cat $DIR/$tfile > /dev/null
21976         cat $DIR/$tfile > /dev/null
21977         cat $DIR/$tfile > /dev/null
21978         cat $DIR/$tfile > /dev/null
21979
21980         local out=$($LFS heat_get $DIR/$tfile)
21981
21982         $LFS heat_get $DIR/$tfile
21983         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
21984         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
21985         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
21986         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
21987
21988         [ $readsample -le 4 ] || error "read sample ($readsample) is wrong"
21989         [ $writesample -le 3 ] || error "write sample ($writesample) is wrong"
21990         [ $readbyte -le 20 ] || error "read bytes ($readbyte) is wrong"
21991         [ $writebyte -le 15 ] || error "write bytes ($writebyte) is wrong"
21992
21993         sleep $((period_second + 3))
21994         echo "Sleep $((period_second + 3)) seconds..."
21995         # The recursion formula to calculate the heat of the file f is as
21996         # follow:
21997         # Hi+1(f) = (1-P)*Hi(f)+ P*Ci
21998         # Where Hi is the heat value in the period between time points i*I and
21999         # (i+1)*I; Ci is the access count in the period; the symbol P refers
22000         # to the weight of Ci.
22001         out=$($LFS heat_get $DIR/$tfile)
22002         $LFS heat_get $DIR/$tfile
22003         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22004         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22005         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22006         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22007
22008         [ $(bc <<< "$readsample <= 4 * $decay_pct / 100") -eq 1 ] ||
22009                 error "read sample ($readsample) is wrong"
22010         [ $(bc <<< "$writesample <= 3 * $decay_pct / 100") -eq 1 ] ||
22011                 error "write sample ($writesample) is wrong"
22012         [ $(bc <<< "$readbyte <= 20 * $decay_pct / 100") -eq 1 ] ||
22013                 error "read bytes ($readbyte) is wrong"
22014         [ $(bc <<< "$writebyte <= 15 * $decay_pct / 100") -eq 1 ] ||
22015                 error "write bytes ($writebyte) is wrong"
22016
22017         echo "QQQQ" > $DIR/$tfile
22018         echo "QQQQ" > $DIR/$tfile
22019         echo "QQQQ" > $DIR/$tfile
22020         cat $DIR/$tfile > /dev/null
22021         cat $DIR/$tfile > /dev/null
22022         cat $DIR/$tfile > /dev/null
22023         cat $DIR/$tfile > /dev/null
22024
22025         sleep $((period_second + 3))
22026         echo "Sleep $((period_second + 3)) seconds..."
22027
22028         out=$($LFS heat_get $DIR/$tfile)
22029         $LFS heat_get $DIR/$tfile
22030         readsample1=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22031         writesample1=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22032         readbyte1=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22033         writebyte1=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22034
22035         [ $(bc <<< "$readsample1 <= ($readsample * (100 - $decay_pct) + \
22036                 4 * $decay_pct) / 100") -eq 1 ] ||
22037                 error "read sample ($readsample1) is wrong"
22038         [ $(bc <<< "$writesample1 <= ($writesample * (100 - $decay_pct) + \
22039                 3 * $decay_pct) / 100") -eq 1 ] ||
22040                 error "write sample ($writesample1) is wrong"
22041         [ $(bc <<< "$readbyte1 <= ($readbyte * (100 - $decay_pct) + \
22042                 20 * $decay_pct) / 100") -eq 1 ] ||
22043                 error "read bytes ($readbyte1) is wrong"
22044         [ $(bc <<< "$writebyte1 <= ($writebyte * (100 - $decay_pct) + \
22045                 15 * $decay_pct) / 100") -eq 1 ] ||
22046                 error "write bytes ($writebyte1) is wrong"
22047
22048         echo "Turn off file heat for the file $DIR/$tfile"
22049         $LFS heat_set -o $DIR/$tfile
22050
22051         echo "QQQQ" > $DIR/$tfile
22052         echo "QQQQ" > $DIR/$tfile
22053         echo "QQQQ" > $DIR/$tfile
22054         cat $DIR/$tfile > /dev/null
22055         cat $DIR/$tfile > /dev/null
22056         cat $DIR/$tfile > /dev/null
22057         cat $DIR/$tfile > /dev/null
22058
22059         out=$($LFS heat_get $DIR/$tfile)
22060         $LFS heat_get $DIR/$tfile
22061         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22062         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22063         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22064         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22065
22066         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22067         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22068         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22069         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22070
22071         echo "Trun on file heat for the file $DIR/$tfile"
22072         $LFS heat_set -O $DIR/$tfile
22073
22074         echo "QQQQ" > $DIR/$tfile
22075         echo "QQQQ" > $DIR/$tfile
22076         echo "QQQQ" > $DIR/$tfile
22077         cat $DIR/$tfile > /dev/null
22078         cat $DIR/$tfile > /dev/null
22079         cat $DIR/$tfile > /dev/null
22080         cat $DIR/$tfile > /dev/null
22081
22082         out=$($LFS heat_get $DIR/$tfile)
22083         $LFS heat_get $DIR/$tfile
22084         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22085         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22086         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22087         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22088
22089         [ $readsample -gt 0 ] || error "read sample ($readsample) is wrong"
22090         [ $writesample -gt 0 ] || error "write sample ($writesample) is wrong"
22091         [ $readbyte -gt 0 ] || error "read bytes ($readbyte) is wrong"
22092         [ $writebyte -gt 0 ] || error "write bytes ($writebyte) is wrong"
22093
22094         $LFS heat_set -c $DIR/$tfile
22095         $LCTL set_param -n llite.*.file_heat=0
22096         echo "Turn off file heat support for the Lustre filesystem"
22097
22098         echo "QQQQ" > $DIR/$tfile
22099         echo "QQQQ" > $DIR/$tfile
22100         echo "QQQQ" > $DIR/$tfile
22101         cat $DIR/$tfile > /dev/null
22102         cat $DIR/$tfile > /dev/null
22103         cat $DIR/$tfile > /dev/null
22104         cat $DIR/$tfile > /dev/null
22105
22106         out=$($LFS heat_get $DIR/$tfile)
22107         $LFS heat_get $DIR/$tfile
22108         readsample=$(echo "$out" | grep 'readsample' | awk '{ print $2 }')
22109         writesample=$(echo "$out" | grep 'writesample' | awk '{ print $2 }')
22110         readbyte=$(echo "$out" | grep 'readbyte' | awk '{ print $2 }')
22111         writebyte=$(echo "$out" | grep 'writebyte' | awk '{ print $2 }')
22112
22113         [ $readsample -eq 0 ] || error "read sample ($readsample) is wrong"
22114         [ $writesample -eq 0 ] || error "write sample ($writesample) is wrong"
22115         [ $readbyte -eq 0 ] || error "read bytes ($readbyte) is wrong"
22116         [ $writebyte -eq 0 ] || error "write bytes ($writebyte) is wrong"
22117
22118         $LCTL set_param -n llite.*.file_heat=$file_heat_sav
22119         rm -f $DIR/$tfile
22120 }
22121 run_test 813 "File heat verfication"
22122
22123 test_814()
22124 {
22125         dd of=$DIR/$tfile seek=128 bs=1k < /dev/null
22126         echo -n y >> $DIR/$tfile
22127         cp --sparse=always $DIR/$tfile $DIR/${tfile}.cp || error "copy failed"
22128         diff $DIR/$tfile $DIR/${tfile}.cp || error "files should be same"
22129 }
22130 run_test 814 "sparse cp works as expected (LU-12361)"
22131
22132 test_815()
22133 {
22134         writeme -b 100 $DIR/$tfile || error "write 100 bytes failed"
22135         writeme -b 0 $DIR/$tfile || error "write 0 byte failed"
22136 }
22137 run_test 815 "zero byte tiny write doesn't hang (LU-12382)"
22138
22139 test_816() {
22140         [ "$SHARED_KEY" = true ] &&
22141                 skip "OSC connections never go IDLE with Shared-Keys enabled"
22142
22143         $LFS setstripe -c 1 -i 0 $DIR/$tfile
22144         # ensure ost1 is connected
22145         stat $DIR/$tfile >/dev/null || error "can't stat"
22146         wait_osc_import_state client ost1 FULL
22147         # no locks, no reqs to let the connection idle
22148         cancel_lru_locks osc
22149         lru_resize_disable osc
22150         local before
22151         local now
22152         before=$($LCTL get_param -n \
22153                  ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22154
22155         wait_osc_import_state client ost1 IDLE
22156         dd if=/dev/null of=$DIR/$tfile bs=1k count=1 conv=sync
22157         now=$($LCTL get_param -n \
22158               ldlm.namespaces.$FSNAME-OST0000-osc-[^M]*.lru_size)
22159         [ $before == $now ] || error "lru_size changed $before != $now"
22160 }
22161 run_test 816 "do not reset lru_resize on idle reconnect"
22162
22163 cleanup_817() {
22164         umount $tmpdir
22165         exportfs -u localhost:$DIR/nfsexp
22166         rm -rf $DIR/nfsexp
22167 }
22168
22169 test_817() {
22170         systemctl restart nfs-server.service || skip "failed to restart nfsd"
22171
22172         mkdir -p $DIR/nfsexp
22173         exportfs -orw,no_root_squash localhost:$DIR/nfsexp ||
22174                 error "failed to export nfs"
22175
22176         tmpdir=$(mktemp -d /tmp/nfs-XXXXXX)
22177         stack_trap cleanup_817 EXIT
22178
22179         mount -t nfs -orw localhost:$DIR/nfsexp $tmpdir ||
22180                 error "failed to mount nfs to $tmpdir"
22181
22182         cp /bin/true $tmpdir
22183         $DIR/nfsexp/true || error "failed to execute 'true' command"
22184 }
22185 run_test 817 "nfsd won't cache write lock for exec file"
22186
22187 test_818() {
22188         mkdir $DIR/$tdir
22189         $LFS setstripe -c1 -i0 $DIR/$tfile
22190         $LFS setstripe -c1 -i1 $DIR/$tfile
22191         stop $SINGLEMDS
22192         #define OBD_FAIL_OSP_CANT_PROCESS_LLOG          0x2105
22193         do_facet $SINGLEMDS lctl set_param fail_loc=0x80002105
22194         start $SINGLEMDS $(mdsdevname ${SINGLEMDS//mds/}) $MDS_MOUNT_OPTS ||
22195                 error "start $SINGLEMDS failed"
22196         rm -rf $DIR/$tdir
22197 }
22198 run_test 818 "unlink with failed llog"
22199
22200 #
22201 # tests that do cleanup/setup should be run at the end
22202 #
22203
22204 test_900() {
22205         [ $PARALLEL == "yes" ] && skip "skip parallel run"
22206         local ls
22207
22208         #define OBD_FAIL_MGC_PAUSE_PROCESS_LOG   0x903
22209         $LCTL set_param fail_loc=0x903
22210
22211         cancel_lru_locks MGC
22212
22213         FAIL_ON_ERROR=true cleanup
22214         FAIL_ON_ERROR=true setup
22215 }
22216 run_test 900 "umount should not race with any mgc requeue thread"
22217
22218 complete $SECONDS
22219 [ -f $EXT2_DEV ] && rm $EXT2_DEV || true
22220 check_and_cleanup_lustre
22221 if [ "$I_MOUNTED" != "yes" ]; then
22222         lctl set_param debug="$OLDDEBUG" 2> /dev/null || true
22223 fi
22224 exit_status